shell脚本中的$0、$n、$#、$-、$?、$!、$$、$*、$@等和shift
我们写别人shell脚本的时候,常会看到$0、$?、$!、$$、$*、$#、$@这样的参数,他们表示什么含义呢?
先看一段脚本打印一下日志:
#!/bin/bash
echo 当前执行脚本: $0
echo 参数个数: $#
echo 参数列表: $@
arguments=($@)
for i in $(seq 1 $#); do
echo 第$i个参数是: ${arguments[`expr $i - 1`]}
done
echo 参数列表: $*
arguments=($*)
for i in $(seq 1 $#); do
echo 第$i个参数是: ${arguments[`expr $i - 1`]}
done
echo 当前shell启动时的选项标志: $-
echo 上一条命令执行后的状态: $?
echo 当前shell的进程ID: $$
echo 这里在一个后台进程输出 &
echo shell最后一次运行的后台进程ID: $!
执行后得到结果:bash ./demo.sh a b c

说明:
$0 表示当前的执行脚本路径,如果是绝对路径,那么结果就是绝对路径,如果是相对路径,结果就是相对路径
$# 表示脚本传进来的时候的参数个数
$n n是大于0的正整数,表示第n个参数,比如$1表示第一个参数,$2表示第二个参数,$5表示第5个参数
$@ 参数列表,每个参数作为单独引用
$* 参数列表,以一个单字符串显示所有向脚本传递的参数
$? 当前shell上一个命令执行后的状态,0表示成功正确执行,否则表示异常代码
$$ 当前shell执行的进程ID
$! 当前shell最后一次启动的后台进程的ID
$- 当前shell的选项标志,表示当前shell的一些设置等,常见的返回结果有
i:交互模式
m:监控模式
B:使用括号展开
H:历史扩展
x:跟踪模式
v:verbose模式
K:禁止globbing(文件名扩展)
h:禁止hashing(命令查找优化)
$@和$*
这两个经常拿来比较,相同点是都可以获取到所有参数,却别在于参数的传递方式不一样,比如:
#!/bin/bash
echo "-- \$* 演示 ---"
for i in "$*"; do echo $i; done
echo "-- \$@ 演示 ---"
for i in "$@"; do echo $i; done

可以看到,$*把所有参数放到一个字符串里面视为一个参数了,而$@是将它们分开了,但是再未使用引号时,两者作用是一样的。
在应用中,我们厂使用$@来传递参数,使用$*来打印内容:
# 使用引号包着,表示把当前脚本的所有参数逐个传递
bash test.sh "$@"
# 打印或者在当前脚本使用
echo 参数列表:$*
shift
这里说下shift,因为我们在写脚本时,往往会使用$@来传递所有的参数,但是往往我们可能有这种需求,我们需要传递的是$@参数列表从第二个参数开始的数据,因为第一个参数可能有特殊含义,这种做法在很多命令里面是很常见的,这个时候,shift可以帮助我们进行在参数列表中进行偏移,看下代码就明白了
#!/bin/bash
echo 当前的参数列表:$*
echo 当前的参数列表:$@
shift
echo 当前的参数列表:$*
echo 当前的参数列表:$@
shift
echo 当前的参数列表:$*
echo 当前的参数列表:$@
执行命令:bash demo.sh a b c d

一个专注于.NetCore的技术小白

浙公网安备 33010602011771号