Shell 脚本变量未定义报错 set -u 如何调试?

文章导读
开启 set -u 后脚本报错,通常是因为引用了未赋值的变量,最稳妥的做法是找出未定义变量并赋予默认值,而不是直接关闭安全检查。
📋 目录
  1. 典型报错复现
  2. 修复方案对比
  3. 调试与定位
  4. 验证方法
  5. 常见坑
  6. 参考来源
A A

开启 set -u 后脚本报错,通常是因为引用了未赋值的变量,最稳妥的做法是找出未定义变量并赋予默认值,而不是直接关闭安全检查。

先说结论:set -u 是防止变量拼写错误导致严重后果的安全机制,调试时应定位具体变量并补充默认值或初始化逻辑。

  • 先确认:报错行号及具体未定义的变量名
  • 先处理:使用 ${VAR:-default} 语法或在使用前初始化
  • 再验证:重新运行脚本确认不再触发 unbound variable 错误

典型报错复现

以下脚本开启了 set -u,但使用了未定义的变量 UNDEFINED_VAR:

#!/bin/bash
set -u
echo "Start"
echo $UNDEFINED_VAR
echo "End"

执行后直接退出,输出如下:

$ bash test.sh
Start
test.sh: line 4: UNDEFINED_VAR: unbound variable

修复方案对比

不要注释掉 set -u,而是修正变量引用方式。

错误写法:

echo $UNDEFINED_VAR

正确写法(赋予默认值):

Shell 脚本变量未定义报错 set -u 如何调试?
echo ${UNDEFINED_VAR:-}

或者在脚本开头统一初始化:

UNDEFINED_VAR=""

调试与定位

如果报错行号不够明确,或变量在函数内部,可结合 bash -x 追踪执行流:

bash -x script.sh 2>&1 | head -n 20

观察最后一行成功执行的命令,报错通常发生在紧随其后的变量展开处。

验证方法

直接运行脚本观察是否还有 unbound variable 报错,并检查脚本逻辑是否符合预期(默认值是否生效)。

bash script.sh

注意:bash -n 仅检查语法错误,无法检测 set -u 导致的运行时未定义变量错误,因此必须实际运行。

常见坑

  • 数组引用:${array[@]} 在数组为空时也可能触发 set -u 错误,需先检查长度或使用 ${array[@]+"${array[@]}"}。
  • 位置参数:$1、$2 等在没有传入参数时视为未定义,需先用 [ -n "$1" ] 判断。
  • 临时关闭风险:不要在关键逻辑段长期使用 set +u,这会掩盖潜在的拼写错误。

参考来源

  • GNU Bash Manual, Section: The Set Builtin, https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
  • POSIX Standard, Shell Command Language, https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html