介绍
这些是 shell 的特殊内置变量,常用于脚本传参、获取脚本名、进程号、返回码等。下面逐个说明,附带示例。
1. 位置参数
脚本传入参数,假设脚本 test.sh,执行命令:
bash test.sh apple banana cat
解释:
$0:脚本本身名称- 如果是
bash test.sh→$0=test.sh - 如果是绝对路径
/root/test.sh→$0=/root/test.sh
- 如果是
$1:第1个参数 →apple$2:第2个参数 →banana$3:第3个参数 →cat${10}:第10个参数。大于9必须加大括号,$10会被解析成$1拼接0。
2. 参数集合:$* 和 $@(重点,容易混淆)
不加引号时,两者效果基本一样;加双引号后行为完全不同
$*:把所有参数当成单个字符串,参数之间用IFS(默认空格)分隔"$*"→"apple banana cat"(一个整体)$@:保留每个参数独立,每个参数单独引号包裹"$@"→"apple""banana""cat"(多个独立参数)
✅ 推荐遍历参数用:for arg in "$@",可以正确处理带空格的参数。
例子
#!/bin/bash
for i in "$*"; do echo "参数: $i"; done
echo "---------"
for i in "$@"; do echo "参数: $i"; done
调用:bash test.sh "a b" c
参数: a b c
---------
参数: a b
参数: c
3. $#:传入参数的个数(不包含 $0)
上面例子 bash test.sh apple banana cat,$# → 3
4. 进程相关
$$:当前 shell 进程PID。脚本里就是脚本运行进程号。$!:上一个后台进程的PID(&放到后台的命令)
sleep 10 &
echo $! # 输出sleep的pid
5. 返回状态码
$?:上一条命令的退出码
0:命令执行成功- 非0:失败
例子
ls /nonexist
echo $? # 输出非0,代表失败
注意:
$?只保存最近一条命令结果,一旦执行新命令就会被覆盖。
6. 其他特殊变量
$_:上一条命令最后一个参数echo hello world echo $_ # world$-:当前shell的选项标志(set的参数,如hB)$PPID:当前进程的父进程PID(不是所有shell都支持,bash有)
汇总表
| 变量 | 含义 |
|---|---|
$0 |
脚本文件名 |
$1,$2... |
第1、2…个位置参数 |
${n} |
n≥10时,第n个参数,必须加大括号 |
$# |
参数总个数(不含$0) |
$* |
所有参数,双引号下合并为1个字符串 |
$@ |
所有参数,双引号下保持参数独立(推荐) |
$$ |
当前shell进程PID |
$! |
最近后台运行进程PID |
$? |
上一条命令退出返回码,0成功 |
$_ |
上一条命令最后一个参数 |
完整测试脚本 demo.sh
#!/bin/bash
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$# = $#"
echo '========== "$*" =========='
for p in "$*"; do echo "[$p]"; done
echo '========== "$@" =========='
for p in "$@"; do echo "[$p]"; done
echo "\$\$ = $$"
echo "\$? = $?"
运行:bash demo.sh "hello world" test 123