linux shell 脚本高频错误有四类:变量未定义或拼写错误,需用 set - u 和引号规范;环境差异致路径或权限问题,应显式设 path 和用绝对路径;条件判断语法不当,须用 [[]] 加引号并区分字符串与数值比较;管道导致子 shell 变量失效,宜改用重定向或命令替换。

Linux Shell 脚本出错很常见,多数问题其实有规律可循。关键不是死记错误码,而是掌握几类高频错误的特征和快速定位方法。
变量未定义或拼写错误
这是最常踩的坑:脚本里写了 $USER_NAME,但实际定义的是 USERNAME;或者忘记用 export 导出变量导致子进程读不到。更隐蔽的是变量名里混入空格或特殊字符,比如 name= "John"(等号前后有空格),会导致赋值失败。
- 运行前加
set -u,脚本能立即报错“unbound variable”,避免静默使用空值 - 用
echo "${VAR:-<default>}"</default>显式处理可能为空的变量 - 检查变量名统一用小写字母 + 下划线,避免大小写混用或中划线
权限、路径与执行环境不一致
脚本在命令行能跑,放进 crontab 就失败?多半是环境差异:crontab 默认 PATH 很窄,找不到 python3 或 jq;又或者脚本用了相对路径 ./data/config.json,但 cron 执行时工作目录不是你预期的位置。
- 在脚本开头显式设置 PATH:
PATH="/usr/local/bin:/usr/bin:/bin" - 所有路径尽量用绝对路径,或先用
cd "$(dirname "$0")"切到脚本所在目录 - cron 中测试时,加上
2>&1 | logger -t myscript把错误日志记下来
条件判断和字符串比较写法不对
if [$a = $b] 看似正常,但如果 $a 为空,实际变成 if [= $b],语法直接报错。还有 [[]] 和 [] 的行为差异(比如通配符匹配、正则支持)也容易混淆。
- 字符串比较一律用双中括号:
if [["$a" == "$b"]],并给变量加双引号 - 判断是否为空用
[[-z "$var"]]或[[-n "$var"]],别用= "" - 数值比较必须用
-eq、-lt等,不能用==(那是字符串操作)
管道与子 shell 导致变量失效
写 echo "1 2 3" | while read n; do count=$((count + 1)); done,结果 count 还是 0 —— 因为管道右侧的 while 在子 shell 里运行,变量修改不会回传到父 shell。
- 避免管道驱动循环,改用
while read重定向:while read n; do …… done - 复杂逻辑拆成函数,用命令替换捕获输出:
result=$(some_command) - 调试时加
set -x查看每条命令实际展开成什么,比猜更可靠
Shell 脚本错误排查不靠运气,靠习惯。加 set -euo pipefail 开头,90% 的低级错误会在第一秒暴露出来。






























