04 · 传递参数

2026.10.08 · 🟢

目标:背熟 7 个特殊变量,分清 $* 和 $@

🎯 今天要带走的三件事

  1. $0 脚本名,$1 $2... 第 n 个参数
  2. $# 参数个数,$? 上条命令退出状态(0 = 成功)
  3. $* vs $@ 只在双引号里有区别

一、基本用法

执行脚本时传参,脚本内用 $n 获取:

#!/bin/bash
echo "执行的文件名:$0"
echo "第一个参数为:$1"
echo "第二个参数为:$2"
echo "第三个参数为:$3"
$ chmod +x test.sh
$ ./test.sh 1 2 3
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

二、特殊变量速查表 ⭐

变量 含义
$0 脚本名(含路径)
$1~$9 第 1~9 个参数
${10} 第 10 个参数(n≥10 必须加花括号)
$# 传递的参数个数
$* 所有参数,作为一个单字符串
$@ 所有参数,每个参数独立
$$ 当前脚本运行的进程 ID
$! 后台运行的最后一个进程 ID
$- Shell 当前选项(同 set 命令)
$? 上一条命令的退出状态(0=无错误)

三、$* 与 $@ 的区别 ⭐

  • 相同点:都引用所有参数
  • 不同点:只在双引号中体现

假设传了 1、2、3 三个参数:

写法 等价于 含义
"$*" "1 2 3" 一个参数
"$@" "1" "2" "3" 三个参数
for i in "$*"; do echo $i; done   # 只输出一行:1 2 3
for i in "$@"; do echo $i; done   # 输出三行:1 / 2 / 3

💡 遍历参数时优先用 "$@",才能正确处理含空格的参数。

四、$? 的陷阱(重点)

# $? 只对"紧邻的上一条命令"负责
demoFun1        # 返回 2
echo $?         # → 2 ✅
echo $?         # → 0 ❌ 已被上一条 echo 覆盖

另外 Shell 里 0 代表真(成功),非 0 代表假(失败),与 C 语言相反:

if echo "Hello" | grep -e Hello; then echo true; else echo false; fi   # true
if echo "Hello" | grep -e Bye;   then echo true; else echo false; fi   # false

🌙 今日作业

  • [ ] 写个脚本打印 $0 $1 $# $*,传 3 个参数运行
  • [ ] 用 "$*" 和 "$@" 各写一个 for 循环,对比输出行数

自测题

  1. 第 10 个参数怎么写?$10 对吗?
  2. $? 的值是 0 代表成功还是失败?
  3. 遍历含空格的参数列表,该用 "$*" 还是 "$@"?
👉 参考答案 1. 写 `${10}`。`$10` 会被解析成 `$1` 后面跟个 `0`,即第一个参数加字符 0。 2. 0 代表**成功**(无错误),非 0 表示失败/错误。注意与 C 的逻辑真假相反。 3. 用 `"$@"`。它会把每个参数当作独立一项,能正确保留参数中的空格。

🔗 关联

Shell-学习总览|上一课 → 03-数组与注释|下一课 → 05-运算符