本部分内容参考自《Linux命令行与shell脚本编程大全 第3版》。
参数统计
特殊变量 $#
含有脚本运行时携带的命令行参数的个数。可以在脚本中任何地方使用这个特殊变量,就跟普通变量一样。
$ cat test17.sh
#!/bin/bash
echo "$# parameters"
$ ./test17.sh 3 2 1
3 parameters
$ ./test17.sh 3 2 1 2 3
5 parameters
如果你仔细考虑过,可能会觉得既然 $#
变量含有参数的总数,那么变量 ${$#}
就代表了最后一个命令行参数变量。试试看会发生什么。
$ cat test18.sh
#!/bin/bash
echo "last parameter is ${$#}"
$ ./test18.sh 1 2 3 2 1
last parameter is 3193
显然,出了点问题。它表明你不能在花括号内使用美元符。必须将美元符换成感叹号。很奇怪,但的确管用。
$ cat test18.sh
#!/bin/bash
echo "last parameter is ${!#}"
$ ./test18.sh 1 2 3 2 21
last parameter is 21
要注意的是,当命令行上没有任何参数时, $#
的值为 0,但 ${!#}
变量会返回命令行用到的脚本名。
$ ./test18.sh
last parameter is ./test18.sh
抓取所有参数
有时候需要抓取命令行上提供的所有参数。这时候不需要先用 $#
变量来判断命令行上有多少参数,然后再进行遍历,你可以使用一组其他的特殊变量来解决这个问题。
$*
和 $@
变量可以用来轻松访问所有的参数。这两个变量都能够在单个变量中存储所有的命令行参数。
$*
变量会将命令行上提供的所有参数当作一个字符串保存。这个字符串包含了命令行中出现的每一个参数值。$*
变量会将这些参数视为一个整体,而不是多个个体。
另一方面, $@
变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。这样你就能够遍历所有的参数值,得到每个参数。这通常通过 for
命令完成。
这两个变量的工作方式不太容易理解。看个例子,你就能理解二者之间的区别了。
$ cat test19.sh
#!/bin/bash
echo "Using the \$* method: $*"
echo "Using the \$@ method: $@"
$ ./test19.sh 1 2 3
Using the $* method: 1 2 3
Using the $@ method: 1 2 3
从表面上看,两个变量产生的是同样的输出,都显示出了所有命令行参数。
下面的例子给出了二者的差异。
$ cat test20.sh
#!/bin/bash
count=1
#
for param in "$*"
do
echo "\$* Parameter #$count = $param"
count=$[ $count + 1 ]
done
#
echo
count=1
#
for param in "$@"
do
echo "\$@ Parameter #$count = $param"
count=$[ $count + 1 ]
done
$ ./test20.sh 1 2 3
$* Parameter #1 = 1 2 3
$@ Parameter #1 = 1
$@ Parameter #2 = 2
$@ Parameter #3 = 3
现在清楚多了。通过使用 for
命令遍历这两个特殊变量,你能看到它们是如何不同地处理命令行参数的。$*
变量会将所有参数当成单个参数,而 $@
变量会单独处理每个参数。这是遍历命令行参数的一个绝妙方法。
评论区