Shell 函数没有形参列表,参数是在调用时传递的。函数内部通过位置参数来访问这些参数。
函数内部用 $1、$2、$3 等来获取第1个、第2个、第3个参数:
greet() {
echo "你好,$1!"
echo "你今年 $2 岁"
echo "来自 $3"
}
greet "小明" 25 "北京"
运行结果:
你好,小明!
你今年 25 岁
来自 北京
参数之间用空格分隔。如果参数本身包含空格,要用引号包起来。
除了 $1、$2 这些,还有一些特殊变量:
| 变量 | 含义 |
|---|---|
$# | 参数个数 |
$@ | 所有参数,每个参数用引号包住 |
$* | 所有参数,合并成一个字符串 |
$? | 上一个命令的退出状态 |
$$ | 当前进程 PID |
show_params() {
echo "参数个数:$#"
echo "第一个参数:$1"
echo "所有参数:$@"
echo "参数列表:"
for param in "$@"; do
echo " - $param"
done
}
show_params apple banana cherry
运行结果:
参数个数:3
第一个参数:apple
所有参数:apple banana cherry
参数列表:
- apple
- banana
- cherry
这两个变量看起来一样,但在引号中表现不同:
test_args() {
echo "使用 \"\$@\":"
for arg in "$@"; do
echo " [$arg]"
done
echo "使用 \"\$*\":"
for arg in "$*"; do
echo " [$arg]"
done
}
test_args "hello world" "foo bar"
运行结果:
使用 "$@":
[hello world]
[foo bar]
使用 "$*":
[hello world foo bar]
"$@" 会保留每个参数的边界,"$*" 会把所有参数合并成一个字符串。绝大多数情况应该用 "$@"。
可以给参数设置默认值,调用时不传就用默认的:
greet() {
local name=${1:-"陌生人"}
local age=${2:-18}
echo "你好,$name,你今年 $age 岁"
}
greet
greet "小红"
greet "小红" 20
运行结果:
你好,陌生人,你今年 18 岁
你好,小红,你今年 18 岁
你好,小红,你今年 20 岁
${变量:-默认值} 的意思是:如果变量不存在或为空,就用默认值。还有几种类似的写法:
${变量:=默认值}:不存在时赋值并使用默认值${变量:+替代值}:变量存在时用替代值${变量:?错误信息}:不存在时报错退出$1 到 $9 可以直接写,第10个及以后的参数要用 ${} 包住:
show_tenth() {
echo "第10个参数是:${10}"
echo "第11个参数是:${11}"
}
shift 命令可以把参数向左移一位,$2 变成 $1,$3 变成 $2,以此类推:
process_args() {
while [ $# -gt 0 ]; do
echo "处理参数:$1"
shift
done
}
process_args a b c d
运行结果:
处理参数:a
处理参数:b
处理参数:c
处理参数:d
shift 在处理命令行选项时特别有用,后面实战章节会详细讲。
$1、$2 等访问,$# 是参数个数"$@" 保留参数边界,推荐使用${变量:-默认值} 可以设置参数默认值${10} 的形式