[Linux Shell学习系列五]Shell编程基础——特殊变量、位置参数、参数类型、数组
1. Bash的内部变量
1)$BASH变量:用于引用Bash实例的全路径名;
$ echo $BASH /bin/bash
2)$HOME变量:当前用户的HOME目录,通常是/home/<username>;
$ echo $HOME /home/user1
3)$IFS变量:内部字段分隔符的缩写;
$ set x y z $ echo "$*" #默认IFS=$' \t\n'
x y z $ set IFS=":;-" #可以修改 $ echo "$*" x:y:z
4)$OSTYPE变量:操作系统的类型;
$ echo $OSTYPE linux-gnu
5)$SECONDS变量:脚本已经运行的秒数;
$ cat echotime.sh #!/bin/bash #2020-05-18 TIME_LIMIT=5 INTERVAL=1 echo echo "Use Ctrl+C to leave before $TIME_LIMIT seconds." echo while [ "$SECONDS" -le "$TIME_LIMIT" ] do sleep $INTERVAL echo $(date) >> /home/ntrade/20200511study/time.log if [ "$SECONDS" -eq 1 ] then units=second else units=seconds fi echo "This script has been running for $SECONDS $units." done
$ ./echotime.sh #执行脚本 Use Ctrl+C to leave before 5 seconds. This script has been running for 1 second. This script has been running for 2 seconds. This script has been running for 3 seconds. This script has been running for 4 seconds. This script has been running for 5 seconds. This script has been running for 6 seconds.
6)$TMOUT变量:如果该变量被设置为非0,则Bash将其作为read默认的超时秒数;
$ cat readtimeout.sh #!/bin/bash #2020-05-18 set -o nounset #Treat unset variables as an error. TMOUT=3 echo "Are you sure? (Y/N)" read input if [ "$input" == "Y" ] then echo "Continue..." else echo "Exit!" fi $ ./readtimeout.sh #执行脚本 Are you sure? (Y/N) #此时如果一直不输入,则3秒后自动退出 Exit!
7)$UID变量:当前用户的帐号标识码(ID号),/etc/passwd中记录值(只读);输出真实ID,即使通过su获得了其他用户的权限。
$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash ... #省略内容 user1:x:1001:1001::/home/user1:/bin/bash $ echo $UID #使用user1执行 1001
2. Bash中的位置参数和特殊参数
Bash中的位置参数是由除0以外的一个或多个数字表示的参数。通过${N}引用(N只有一位时可以用$N)。
位置参数不能通过赋值语句来赋值:
1)通过Bash的set和shift来设置和取消;
$ set one two three $ echo $1 $2 $3 one two three
2)当Shell或Shell的函数被引用时,由Shell或Shell函数的参数赋值。
$ cat positionalpara.sh #!/bin/bash #2020-05-18 echo "Argument 1 is: $1" echo "Argument 2 is: $2" echo "Argument 2 is: $3" $ ./positionalpara.sh one two three Argument 1 is: one Argument 2 is: two Argument 2 is: three
Bash对一些参数处理比较特殊:只能被引用,但不能修改它们的值。
分别是:*、@、#、?、-、$、!、0和_。
1)特殊参数*:扩展为从1开始的所有位置参数。
如果扩展发生在双引号内,即"$*",则扩展为包含每个参数值的单词,参数之间用特殊变量IFS的第一个字符分隔。
$ set one two three #set $ echo "$*" one two three $ cat positionalpara.sh #脚本 #!/bin/bash #2020-05-18 echo "Arguments: $*" $ ./positionalpara.sh one two three Arguments: one two three
2)特殊参数@:扩展为从1开始的所有位置参数。
当扩展发生在双引号内,每个参数都扩展为分隔的单词;$@通过for循环的调用体现与$*的不同。
$ set one two three $ echo "$@" one two three $ cat positionalpara.sh #脚本 #!/bin/bash #2020-05-18 for arg in "$*" #使用for循环打印$*中的元素 do echo "item in \$* is: $arg" done for arg in "$@" #使用for循环打印$@中的元素 do echo "item in \$@ is: $arg" done $ ./positionalpara.sh one two three item in $* is: one two three #只有一个元素,是各个参数连接而成的字符串 item in $@ is: one #每个参数是独立的 item in $@ is: two item in $@ is: three
3)特殊参数#:扩展为位置参数的个数,用十进制表示:
$ set one two three $ echo "$#" 3
4)特殊参数?:扩展为最近一个在前台执行的命令的退出状态。
可以使用它来检查Shell脚本是否成功执行,通常0表示正确结束。
$ touch newfile $ echo "$?" 0 $ rm -f newfile $ echo "$?" 0 $ ls newfile ls: cannot access newfile: No such file or directory $ echo "$?" 2 $ touchwrong newfile -bash: touchwrong: command not found $ echo "$?" 127
补充:
转载:
版权声明:本文为CSDN博主「_荣耀之路_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/asty9000/java/article/details/86681890
Shell脚本有三种方式返回退出码:
1.exit命令,用exit返回退出码,exit后的指令不会再执行。
2.return命令,但是要注意的是只有用source方式调用的脚本中才能用return返回退出码,return后的指令同样不会再执行。
3.如果脚本中既没有exit也没有return,则脚本的退出码为脚本中最后一条指令的退出码。
Shell函数有两种方式返回退出码:
1.return命令,return后的指令不会再执行。
2.如果没有return,则函数的退出码为函数中最后一条指令的退出码。
在脚本或函数执行完成后,紧接着通过$?就可以获得脚本或函数的退出码。
Linux退出码的有效值为0-255,以下为保留的退出码。
| 退出码 | 说明 |
|
1 |
通用错误,任何错误都可能使用这个退出码。 |
| 2 | shell内建命令使用错误 |
| 126 | 命令调用不能执行。 |
| 127 | command not found,找不到命令 |
| 128 | exit参数错误,exit只能以整数作为参数。 |
| 128+n | 信号"n"的致命错误,如kill -9 脚本的PID,则返回137(128+9)。 |
| 130 | 用Control-C来结束脚本,用Control-C是信号2的致命错误。 |
当返回的退出码大于255时,会将其对256取模。return只能返回大于0的整数。exit可以返回任意整数,但是超过有效范围的值会对256取模。
5)特殊参数-:将扩展为当前的选项标志。
这些选项是在调用时,或由内部命令set指定,或有Shell自身指定。
[ntrade@host-192-168-164-20 ~/20200511study]$ echo "$-" himBH #每个字符对应下面一个打开的选项 [ntrade@host-192-168-164-20 ~/20200511study]$ set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
注:具体选项的规则见shell选项设置
6)特殊参数$:将扩展为当前Shell的进程号。
在一个子Shell中,它扩展为调用Shell的进程号,而不是子Shell的进程号。
$ ps -ef|grep bash ... user1 12500 12499 0 10:51 pts/0 00:00:00 -bash #当前Shell $ echo $$ 12500
对于 Shell 脚本,就是这些脚本所在的进程ID。
$ cat childprocess.sh #!/bin/bash ps -ef|grep childprocess.sh echo $$ $ cat shellprocess.sh #!/bin/bash ps -ef|grep shellprocess.sh echo $$ ./childprocess.sh $ ./shellprocess.sh user1 23067 12500 0 14:23 pts/0 00:00:00 /bin/bash ./shellprocess.sh user1 23069 23067 0 14:23 pts/0 00:00:00 grep shellprocess.sh 23067 #这里是shellprocess打印的$$ user1 23070 23067 0 14:23 pts/0 00:00:00 /bin/bash ./childprocess.sh user1 23072 23070 0 14:23 pts/0 00:00:00 grep childprocess.sh 23070 #这里是childprocess打印的$$
7)特殊参数!:将扩展最近一次执行的后台命令的进程号
$ sleep 10 & #后台命令 [1] 23239 $ echo $! 23239
8)特殊参数0:将扩展为Shell或Shell脚本的名称。在Shell初始化时设置。
如果Bash调用时带有脚本文件作为参数,$0就设置为脚本的文件名。
$ cat para0.sh #!/bin/bash echo "\$0 is: $0" $ ./para0.sh $0 is: ./para0.sh $ bash ./para0.sh $0 is: ./para0.sh $ /home/user1/20200511study/para0.sh $0 is: /home/user1/20200511study/para0.sh
9)特殊参数_:当Shell启动时,被设为开始运行的Shell或Shell脚本的路径。随后,扩展为前一个命令的最后一个参数。
$ cat para_underscore.sh #!/bin/bash echo "\$_ is: $_" ls -l ./ #执行ls命令 echo "New \$_ is: $_" $ ./para_underscore.sh #执行脚本,结果如下: $_ is: ./para_underscore.sh #这里为Shell脚本的路径 total 16 -rw-rw-r--. 1 user1 user1 19 May 15 10:42 a.txt -rw-rw-r--. 1 user1 user1 12 May 15 09:36 b.txt -rw-rw-r--. 1 user1 user1 6 May 15 09:36 c.txt -rwxrwxr-x. 1 user1 user1 64 May 18 14:35 para_underscore.sh New $_ is: ./ #这里扩展为ls -l ./命令的最后一个参数,即./
3. 使用declare指定变量的类型
declare命令是Bash的内部命令,用于声明变量和修改变量的属性。与另一个内部命令typeset命令用法和用途完全相同。
$ declare #显示所有变量的值 BASH=/bin/bash BASHOPTS=... ... #省略输出 $ declare -r var=1 #使用-r选项:声明一个只读变量,该变量的值无法改变,并且不能为unset $ var=2 -bash: var: readonly variable $ unset var -bash: unset: var: cannot unset: readonly variable $ declare -i NUMBER #使用-i选项:声明一个整型 $ NUMBER=1 $ echo $NUMBER 1 $ NUMBER=one $ echo $NUMBER 0 $ NUMBER=9/2 $ echo $NUMBER 4 $ declare -p var #使用-p选项:显示指定变量的属性和值 declare -r var="1 $ declare -p NUMBER declare -i NUMBER="4" # declare -a cd='([0]="a" [1]="b" [2]="c")' #使用-a选项:声明数组变量 # echo ${cd[1]} #显示变量内容 b # echo ${cd[@]} #显示整个数组变量内容 a b c $ function func_echo() { #这里定义一个函数 > echo $1 > } $ declare -f #使用-f选项:打印所有函数定义 func_echo () { echo $1 } $ declare -F #使用-F选项:仅打印所有函数名字 declare -f func_echo $ declare -x PATH=$PATH:/home/user1/20200511study/test/ #使用-x选项:与export的作用类似
4. Bash中的数组变量
一个数组是包含多个值的变量。任何变量也可以作为一个数组使用。数组大小没有限制,也不需要连续分配成员变量。数组的索引从0开始。
间接声明数组变量的语法:$ ARRAYNAME[index]=value #INDEX是正数
显式声明数组变量:$ declare -a ARRAYNAME
$ declare -a nums=(1 2 3) #声明并赋值
$ NUMBER=6 $ nums=(2 3 $NUMBER) #通过变量赋值
$ echo "${nums[@]}" #引用所有元素的值组合成的字符串 2 3 6 $ echo ${nums[0]} ${nums[1]} ${nums[2]} 2 3 6 $ echo ${nums[*]} #引用所有元素的值组合成的字符串 2 3 6 $ echo ${nums[@]} #引用所有成员 2 3 6 $ nums[3]=8 #通过索引添加元素 $ echo ${nums[@]} 2 3 6 8 $ echo $nums #引用数组时不指定索引,则使用索引编号0,即第一个元素 2 $ unset nums[2] #消除一个元素 $ echo ${nums[*]} 2 3 8 $ echo ${nums[2]} #输出空 $ unset nums #消除一个数组 $ echo ${nums[@]} #输出空
Bash的各种参数扩展也可以应用于数组变量。
本节结束

浙公网安备 33010602011771号