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% 的低级错误会在第一秒暴露出来。










