Shell Daily 2025-12-17: 变量默认值 (Parameter Expansion)

Shell Daily 2025-12-17: 变量默认值 (Parameter Expansion)

写脚本时,你是不是经常为了给变量设一个默认值,写出类似这样的防御性代码?

# 笨办法
if [ -z "$DB_HOST" ]; then
    DB_HOST="localhost"
fi

为了这点小逻辑写四行代码,不仅啰嗦,还会打断阅读思路。其实,Shell 原生就内置了一套极其强大的 参数扩展 (Parameter Expansion) 语法,专门优雅地处理“如果变量为空”的情况。

怎么用

这种语法通常长这样:${变量名:-默认值}。注意中间的冒号 -

  • 语法
    • ${VAR:-default}:如果 VAR 未设定或为空,返回 default。VAR 本身的值不变
    • ${VAR:=default}:如果 VAR 未设定或为空, default 赋值给 VAR,并返回该值。
  • 兼容性POSIX 通用标准。无论是 Bash, Zsh, Dash 还是嵌入式环境的 Ash,都放心使用。

适用场景

编写通用的配置脚本、Docker 入口脚本 (entrypoint) 或任何需要允许用户通过环境变量覆盖默认行为的场景。

示例 1:临时读取默认值

假设你在写一个备份脚本,用户没传目标目录,就默认用 /tmp。不需要真正改变变量,只是读取时判断一下:

# 如果 $BACKUP_DIR 没定义,就输出 /tmp,否则输出 $BACKUP_DIR
echo "Backing up to: ${BACKUP_DIR:-/tmp}..."

示例 2:永久赋值默认值 (推荐)

这是最能替代 if [ -z ] 的写法。通常放在脚本开头统一初始化变量:

# 如果环境变量没有提供 PORT,则将 PORT 赋值为 8080
: ${PORT:=8080}
# 如果没有提供超时时间,默认为 30 秒
: ${TIMEOUT:=30}

echo "Starting server on port $PORT with timeout ${TIMEOUT}s."

(注:开头的 : 是 Shell 的空命令。我们只需要利用参数扩展的“赋值副作用”,不需要执行结果,所以用冒号接住它,非常干净。)

示例 3:强制参数必填

还有一个变体 ${VAR:?message},如果变量为空,Shell 会自动打印错误信息并终止脚本执行。非常适合检查必须的依赖:

# 如果 API_TOKEN 为空,脚本会立即退出并报错
curl -H "Authorization: ${API_TOKEN:?Error: API Token is required!}" https://api.example.com
posted @ 2025-12-17 18:32  Terrasse  阅读(6)  评论(0)    收藏  举报