排查Shell脚本语法错误应分层定位:先查shebang和换行符(如^M导致解析失败),再用bash -n做静态检查,接着用bash -x追踪变量展开,最后验证shell兼容性(如dash不支持[[ ]]或数组)。

排查复杂的 Shell 脚本语法错误,关键不是盲目逐行检查,而是分层定位:先确认脚本是否被正确解析,再验证语法结构,最后分析运行时展开逻辑。多数“syntax error near unexpected token”类报错,根本原因不在代码写错,而在 shell 启动方式或文本格式异常。
第一步:查 shebang 和换行符
这是最常被忽略却最高发的根源:
- 用
head -n1 script.sh | cat -A查首行真实内容——若末尾显示^M,说明是 Windows 换行符(\r\n),shell 实际读到的是#!/bin/bash\r,把\r当作非法 token 报错 - 修复方式:
dos2unix script.sh,或sed -i 's/\r$//' script.sh - 确认 shebang 路径真实存在:
ls -l /bin/bash;某些精简系统(如 Alpine)只有/bin/sh,写成#!/bin/bash却用sh script.sh执行,也会触发该错误 - 注意执行方式差异:
./script.sh依赖 shebang;sh script.sh强制用 sh,完全无视 shebang
第二步:用 -n 选项做静态语法检查
不运行脚本,只让 shell 解析并报告语法问题:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 用对应解释器执行:
bash -n script.sh(脚本以#!/bin/bash开头)或sh -n script.sh(以#!/bin/sh开头)。混用会导致误判——比如 bash 支持[[ ]],sh 不支持,用 bash -n 可能漏掉 sh 下的真实错误 - 典型报错如
unexpected EOF while looking for matching '"',说明引号没闭合;syntax error near unexpected token `then'往往是if后少了空格或[写成了[(缺空格) - 对含变量或命令替换的行要特别小心:
echo "$(date) $USER"若$USER为空且未加引号,可能意外破坏结构
第三步:用 -x 追踪实际执行流
语法通过但运行时报错?大概率是变量展开或命令替换生成了非法语句:
- 临时启用:
bash -x ./script.sh,无需改脚本,直接看到每条命令展开后的样子 - 在脚本内精准控制范围:开头加
set -x,关键段落结束后加set +x,避免输出过载 - 重点盯
$()或反引号内的命令输出——如果其中含未转义的换行、|、&或括号,就会导致后续解析失败 - 例如:
cmd=$(some_tool)若工具输出带换行,if [ $cmd = "ok" ]就会变成多行语句,直接崩
第四步:检查 shell 兼容性与环境差异
同一段脚本在不同机器上表现不一?很可能是 shell 类型或版本差异:
- Alpine 默认用
ash,Ubuntu/Debian 的/bin/sh常是dash,都不支持[[ ]]、let、数组arr=(a b)、{1..3}等 bash 特性 - 可移植写法建议:
[ ]替代[[ ]];case替代正则匹配;避免$(( ))外的算术扩展;字符串比较统一用"$var" = "value"加引号 - 确认目标环境默认 shell:
echo $0或ps -p $$;容器中尤其要注意基础镜像用的是什么 shell

















