$0:当前脚本的文件名
$n:第n个位置参数
$*:传递给脚本或函数的所有参数,$*会将这些参数视为一个整体
$@:传递给脚本或函数的所有参数,$@会将所有参数当作同一字符串中的多个独立的单词
$#:脚本运行时携带的参数个数
$?:最近一个命令的退出状态码
$$:当前shell的进程ID(PID)
$!:最近一个后台命令的PID
!!:执行上一条命令
IFS:内部字段分隔符,IFS环境变量定义了shell用作字段分隔符的一系列字符。默认情况下,shell会将下列字符当做字段分隔符:
&>:将STDERR和STDOUT的输出重定向到同一个输出文件
&-:要关闭文件描述符,可以将它重定向到特殊符号&-
.:点操作符,点操作符是source命令的别名,它会在shell上下文中执行点操作符指定的脚本,而不是创建一个新的shell。
shell退出状态码是一个0-255的整数值,在命令结束时由命令传给shell,对于需要检查的命令,必须在其运行完毕后立刻查看或使用$?变量。默认情况下,shell脚本会以脚本中最后一个命令的退出状态码退出,你也可以自己修改退出状态码,通过exit命令允许你在脚本结束时指定一个退出状态码,如下所示:
#!/bin/bash
var1=10
var2=10
exit $[ $var1 + $var2 ]
运行脚本之后查看$?:
那现在有一个问题,因为退出状态码最大是255,那如果我们设置的退出状态码大于255会怎样?我们将上述代码的var1修改为300,运行脚本之后查看$?:
结果是54,退出状态码被缩减到了0-255之间,其实是shell通过对256取模得到的余数作为状态码。
shell会将一些称为位置参数的特殊变量分配给输入到命令行中的所有参数,包括脚本名称。位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9。
当脚本需要的命令行参数不止9个时,需要修改一下变量名,在第9个变量之后,你必须在变量数字的周围加上花括号,比如${10}。我们来看一个脚本程序:
#!/bin/bash
echo the script is $0
echo the script is $(basename $0)
echo the 10th parameter is ${10}
运行结果为:
如果直接输出$0,程序会输出你输入的脚本路径+脚本名称,通过basename可以返回不包含路径的脚本名。
$#含有脚本运行时携带的参数个数,可以在脚本中的任何地方使用该变量。既然$#代表参数个数,那变量${$#}岂不是就代表了最后一个命令行参数变量,我们来看一段脚本程序:
#!/bin/bash
echo the last param is ${$#}
echo the last param is ${!#}
params=$#
echo the last param is $params
运行结果为:
使用${$#}来访问最后一个参数是不可行的,可以将${$#}替换为${!#}或者使用脚本中的另一种方式来访问最后一个参数。当没有参数时,$#为0,且${!#}会返回命令行用到的脚本名称。
$*和$@都可以用来轻松访问所有的参数,只不过$*会将这些参数视为一个整体,而不是多个个体。$@会将所有参数当作同一字符串中的多个独立的单词。我们来看一个程序:
#!/bin/bash
echo "Usint the \$* method: $*"
echo "Using the \$@ method: $@"
echo
count=1
for param in "$*"
do
echo "\$* params #$count = $param"
count=$[ $count + 1 ]
done
count=1
for param in "$@"
do
echo "\$@ params #$count = $param"
count=$[ $count + 1 ]
done
可以看到,$*会将所有参数当作单个参数,而$@会单独处理每个参数。
!!就是执行上一个命令,历史命令会更新到~/.bash_history当中,该文件记录的历史命令条数通过HISTSIZE环境变量指定:
假设我这次登录主机后,执行了100次命令,等我注销时,系统会将101~1100总共1000笔历史命令更新到~/.bash_history文件中。当然也可以使用history -w强制立刻写入,仅保留最新的命令。可以通过history来查看历史命令(通过history 5来查看最近的5条命令):
有以下三种方式来执行历史命令:
执行~/.bash_history当中的第number条命令
由最近的命令向前搜寻首个命令串开头为command的命令,并执行
执行上一条命令
使用~/.bash_history来记录历史命令有一个问题:同一账号同时多次登录的history写入问题。因为注销时才会更新记录文件,所以最后注销的那个bash才会是最后写入的数据,而其他bash的命令操作其实也被记录了,只不过被最后一个bash操作覆盖了。所以,一般一个账户都会单一bash登录,再用作业控制来切换不同的工作。
单引号内的内容原样输出,而在双引号中,如果内容中有命令,变量等,会先把变量,命令解析出结果,然后在输出最终内容来,我们看如下代码:
#!/bin/bash
var="hello"
echo "var: $var"
echo 'var: $var'
运行结果: