脚本跑不通先别急着重写:用 set -x 和日志把 Shell 脚本讲清楚
写 Shell 脚本时最让人头疼的不是语法报错,而是脚本“静悄悄地跑偏了”:没有报错、退出了,但结果就是不对。很多人第一反应是把脚本推倒重写,或者凭感觉改几处再跑一次,结果往往是旧问题没解决,又引入新问题。先把脚本的执行过程讲清楚,再动手改,顺序不能反。set -x 和日志,就是干这件事最顺手的两个工具。
第一步是先用 set -x 看脚本到底执行了什么。bash -x 脚本名,或者在脚本开头加上 set -x,Shell 会把每一条实际执行的命令原样打印出来,包括变量展开后的值。很多问题一看就明白:变量是空的、路径拼错了、条件判断走进了意料之外的分支。没有这一步,排查只能靠猜;有了这一步,问题就从“脚本不对”变成“某一行不对”。
第二步是区分变量问题和逻辑问题。set -x 的输出里,先看变量的值是不是你以为的那个。常见情况有三种:一是变量根本没有赋值,比如拼写错了一个字母,Shell 默认把未定义变量当成空字符串,不报错;二是变量里有空格或特殊字符,没有加引号,导致一个值被拆成了好几个参数;三是命令替换的结果和预期不同,比如用反引号或 $() 拿到了一行带换行符的输出。确认变量没问题,再看分支和循环的走向,范围就小多了。
第三步是把关键步骤写进日志,而不是只靠终端输出。脚本在终端跑和在定时任务里跑,环境并不一样:定时任务的 PATH 更短、工作目录不同、没有交互终端。终端上能跑通的脚本,放进 crontab 里可能就失败了,而且失败时没有任何输出可以看。正确的做法是把脚本的标准输出和标准错误重定向到日志文件,关键步骤再加上一行带时间的 echo,比如“开始备份”“备份完成,共多少文件”。出问题时先看日志的最后几行,再决定要不要开 set -x 细查。
第四步是做最小复现。把怀疑出问题的那一段单独抽出来,用最小的输入跑一次:如果单独跑能成功,说明问题在它前面的步骤,比如某个变量在前面被改掉了;如果单独跑也失败,问题就在这一段本身。这个二分过程,比从头到尾通读几百行脚本更快,也更容易验证修复是否真的生效。
最后养成三个习惯:一是脚本开头写上 set -euo pipefail,让错误尽早暴露,而不是带着错误值继续往下跑;二是所有变量引用都加双引号,避免空格拆分带来的意外;三是重要的脚本都留一份日志,并定期看一眼日志里有没有警告。脚本问题很少是孤立的语法错误,多半是某个变量、某条路径或某个环境差异。先开追踪、再看日志、最后才改代码,脚本跑不通的排查才不会越改越乱。
- 点赞
- 收藏
- 关注作者
评论(0)