$(...)可以扩展成另一个命令的运行结果,该命令的所有输出都会作为返回值。
echo $(date)Tue 30 Nov 2021 05:26:45 CST
上面例子中,$(date)返回date命令的运行结果。
单引号用于保留字符的字面含义,各种特殊字符在单引号里面,都会变为普通字符,比如星号(*)、美元符号($)、反斜杠(\)等。
由于反斜杠在单引号里面变成了普通字符,所以如果单引号之中,还要使用单引号,不能使用转义,需要在外层的单引号前面加上一个美元符号($),然后再对里层的单引号转义。
echo $'it\'s'
双引号比单引号宽松,大部分特殊字符在双引号里面,都会失去特殊含义,变成普通字符。
但是,三个特殊字符除外:美元符号($)、反引号(`)和反斜杠(\)。这三个字符在双引号之中,依然有特殊含义,会被 Bash 自动扩展。
反斜杠在双引号之中保持特殊含义,用来转义。所以,可以使用反斜杠,在双引号之中插入双引号,或者插入反斜杠本身。
如果变量的值包含空格,则必须将值放在引号中。
var="hello world"
Bash 没有数据类型的概念,所有的变量值都是字符串。
如果变量值包含连续空格(或制表符和换行符),最好放在双引号里面读取。如果直接读取,Shell 会将连续空格合并成一个。只有放在双引号里面读取,才能保持原来的格式。
a="1 2 3"echo "$a"
读取变量的时候,变量名也可以使用花括号{}包围。这种写法可以用于变量名与其他字符连用的情况。事实上,读取变量的语法$foo,可以看作是${foo}的简写形式。
$?: 上一个命令的退出码,用来判断上一个命令是否执行成功。返回值是0,表示上一个命令执行成功;如果不是零,表示上一个命令执行失败。
$0: 当前 Shell 的名称(在命令行直接执行时)或者脚本名(在脚本中执行时)。
$#: 脚本的参数数量。
$@: 脚本的参数值,参数之间使用空格分隔。
$1 ~ $9: 对应脚本的第一个参数到第九个参数。
如果脚本的参数多于9个,那么第10个参数可以用${10}的形式引用,以此类推。
getopts命令用在脚本内部,可以解析复杂的脚本命令行参数,通常与while循环一起使用,取出脚本所有的带有前置连词线(-)的参数。
getopts optstring name
第一个参数optstring是字符串,给出脚本所有的连词线参数。比如,某个脚本可以有三个配置项参数-l、-h、-a,其中只有-a可以带有参数值,而-l和-h是开关参数,那么getopts的第一个参数写成lha:,顺序不重要。注意,a后面有一个冒号,表示该参数带有参数值,getopts规定带有参数值的配置项参数,后面必须带有一个冒号(:)。getopts的第二个参数name是一个变量名,用来保存当前取到的配置项参数,即l、h或a。
while getopts 'lha:' OPTION; do
case "$OPTION" in
l)
echo "linuxconfig"
;;
h)
echo "h stands for h"
;;
a)
avalue="$OPTARG"
echo "The value provided is $OPTARG"
;;
?)
echo "script usage: $(basename $0) [-l] [-h] [-a somevalue]" >&2
exit 1
;;
esac
done
shift "$(($OPTIND - 1))"上面例子中,while循环不断执行getopts 'lha:' OPTION命令,每次执行就会读取一个连词线参数(以及对应的参数值),然后进入循环体。变量OPTION保存的是,当前处理的那一个连词线参数(即l、h或a)。如果用户输入了没有指定的参数(比如-x),那么OPTION等于?。循环体内使用case判断,处理这四种不同的情况。
如果某个连词线参数带有参数值,比如-a foo,那么处理a参数的时候,环境变量$OPTARG保存的就是参数值。
注意,只要遇到不带连词线的参数,getopts就会执行失败,从而退出while循环。比如,getopts可以解析command -l foo,但不可以解析command foo -l。另外,多个连词线参数写在一起的形式,比如command -lh,getopts也可以正确处理。
变量$OPTIND在getopts开始执行前是1,然后每次执行就会加1。等到退出while循环,就意味着连词线参数全部处理完毕。这时,$OPTIND - 1就是已经处理的连词线参数个数,使用shift命令将这些参数移除,保证后面的代码可以用$1、$2等处理命令的主参数。