主题
12 · 变量、参数、条件与退出码
目标:用位置参数、
if/case与退出码写出可被其他脚本调用的逻辑。
前置:11 · 第一个脚本
1. 环境前提
bash
mkdir -p ~/lab/scripts1
2. 变量与环境变量
bash
#!/usr/bin/env bash
set -euo pipefail
APP_NAME="mini-api" # 脚本内变量
export LAB_ROOT="$HOME/lab" # 导出后子进程可见
echo "APP_NAME=$APP_NAME"
echo "PATH 长度: ${#PATH}"
echo "未设置时用默认: ${TIMEOUT:-10}"1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
| 写法 | 含义 |
|---|---|
"$var" | 展开(推荐) |
${var:-default} | 空或未设置时用默认 |
${#var} | 字符串长度 |
readonly X=1 | 只读 |
算术用 (( )) 或 $(( )):
bash
n=3
echo $((n + 1))1
2
2
3. 位置参数
| 特殊变量 | 含义 |
|---|---|
$0 | 脚本名 |
$1 $2 … | 第 1、2… 个参数 |
$# | 参数个数 |
"$@" | 全部参数(保边界,推荐) |
"$*" | 合成一个字符串(少用) |
bash
cat > ~/lab/scripts/greet.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "用法: $0 <名字>" >&2
exit 2
fi
echo "hello, $1"
EOF
chmod 755 ~/lab/scripts/greet.sh
~/lab/scripts/greet.sh Ada
~/lab/scripts/greet.sh # 应退出码 2
echo "exit=$?"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>&2:错误信息打到 stderr,方便管道只收「正常输出」。
4. 退出码
约定(本系列):
| 码 | 含义 |
|---|---|
0 | 成功 |
1 | 一般失败 |
2 | 用法/参数错误 |
| 其它 | 按场景自定义,并在注释写明 |
bash
true; echo $? # 0
false; echo $? # 11
2
2
调用方:
bash
if ~/lab/scripts/greet.sh Ada; then
echo "greet ok"
fi1
2
3
2
3
5. if / [[ ]] / case
Bash 推荐 [[ ]](不是旧式 [ ]):
bash
cat > ~/lab/scripts/check-file.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
path="${1:-}"
if [[ -z "$path" ]]; then
echo "用法: $0 <路径>" >&2
exit 2
fi
if [[ -f "$path" ]]; then
echo "普通文件: $path"
elif [[ -d "$path" ]]; then
echo "目录: $path"
else
echo "不存在或不支持: $path" >&2
exit 1
fi
EOF
chmod 755 ~/lab/scripts/check-file.sh
~/lab/scripts/check-file.sh ~/lab/scripts/greet.sh1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
常用测试:
| 表达式 | 含义 |
|---|---|
-z "$s" | 空字符串 |
-n "$s" | 非空 |
-f / -d / -e | 文件 / 目录 / 存在 |
"$a" == "$b" | 字符串相等 |
"$n" -lt 10 | 整数比较(-eq -ne -lt -le -gt -ge) |
case:
bash
cmd="${1:-status}"
case "$cmd" in
start) echo "start" ;;
stop) echo "stop" ;;
status) echo "status" ;;
*)
echo "未知命令: $cmd" >&2
exit 2
;;
esac1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
6. 命令成功与否
bash
if curl -fsS -o /dev/null "http://127.0.0.1:8080/health"; then
echo "up"
else
echo "down"
fi1
2
3
4
5
2
3
4
5
curl -f:HTTP 错误当失败;-sS:安静但仍显示错误(14 篇会用到)。
7. 动手清单
- [ ]
greet.sh:无参数退出 2,有参数打印问候 - [ ]
check-file.sh:分别测文件、目录、不存在路径 - [ ] 写一个
case接受start|stop|status - [ ] 看清
echo $?在成功/失败后的值
8. 常见翻车
| 翻车 | 处理 |
|---|---|
set -u 下 $1 未传直接炸 | 先判 $#,或 "${1:-}" |
[ $a = $b ] 空格/空值翻车 | 改用 [[ "$a" == "$b" ]] |
| 错误信息混进管道结果 | 用法说明走 >&2 |
忘记 exit | 调用方以为成功 |
9. 官方入口
- Bash Conditional Constructs
help [[、help test、help case
下一篇:循环、函数与脚本结构 —— 把多文件、重复逻辑收干净。
