set -x 是 Bash 调试开关,执行前打印含展开变量的实际命令到 stderr,配合日志可追踪执行路径、参数和分支;适用于环境差异、判断异常、网络命令失败或静默退出等场景。

set -x 是 Bash 脚本中开启“调试模式”的开关,它会让 Shell 在执行每条命令前,先把这条命令(含变量展开后的实际值)打印到标准错误(stderr)上。配合日志文件,就能把脚本的完整执行路径、参数取值、分支走向都记录下来,是定位“脚本行为和预期不符”类故障最直接有效的手段。
什么时候该用 set -x + 日志
当你遇到这些情况时,别急着改逻辑,先加日志:
- 脚本在服务器上运行失败,但本地能过——可能是环境变量、路径、权限或依赖命令版本不一致;
- if 判断结果不对,echo 变量值却显示正常——实际执行的可能是未展开的变量或空字符串;
- curl 或 ssh 命令莫名超时或返回非零码,但手动敲一遍又成功——说明上下文(如当前目录、环境变量、重定向)影响了行为;
- 脚本中途退出,没报错也没提示——可能某条命令失败后没做错误检查,而 set -x 能让你看到卡在哪一行。
怎么安全地开启并保存调试日志
不要直接在生产脚本里写死 set -x,推荐两种稳妥方式:
-
临时运行时开启:执行脚本时加上 -x 参数,同时重定向 stderr 到日志文件:
bash -x ./deploy.sh > deploy.log 2>&1 -
脚本内条件启用:在脚本开头加判断,只在指定环境下输出调试信息:
if [[ "${DEBUG:-0}" == "1" ]]; then set -x; fi
运行时只需 DEBUG=1 ./deploy.sh > deploy.log 2>&1,不影响默认行为。
看日志时重点盯什么
日志不是从头读,而是带着问题查线索。重点关注三类行:
- 带 + 号的命令行:比如 + curl -s http://api.example.com/v1/status?token=$TOKEN——确认 $TOKEN 是否真的有值、是否被 URL 编码污染;
-
命令返回状态:虽然 set -x 不打印 $?,但下一行如果是 if 或 &&,就能看出上条命令是否失败。例如:
+ [ -f /etc/myapp/config.yaml ]
+ echo "Config exists"
如果 config.yaml 不存在,第二行就不会出现; - 路径和重定向变化:比如 + cd /tmp && cp data.txt /opt/app/,要核对 cd 是否成功(可用 pwd 验证),避免后续操作在错误目录执行。
配合其他命令提升排查效率
单靠 set -x 日志还不够,常搭配以下操作快速定位:
- 用 grep "^+ " 提取所有执行命令,过滤无关输出;
- 在关键位置插入 echo "DEBUG: var=\$var" >&2,比 set -x 更精准地打点变量快照;
- 结合 set -e(遇错退出)和 set -u(未定义变量报错),让脚本在异常初期就中断,配合日志更容易回溯。











