1. 主页 > 小妙招

Shell脚本常见报错解决指南:手把手教你调试.sh文件


为什么你的脚本总像叛逆期的孩子?

刚写完脚本满心欢喜按回车,结果蹦出来个"syntax error near unexpected token"?别慌!这就像炒菜忘开煤气灶——九成新手都会栽的坑。咱们先来破解几个经典报错场景。


场景一:中括号引发的血案

??报错提示??:"[: missing ]"
这破问题折磨过90%的Shell初学者。看这段问题代码:

bash复制
if [ $num == 10 ]  # 错误!中括号和变量之间没空格
then
    echo "对了"
fi

??正确打开方式??:

bash复制
if [ $num -eq 10 ]  # 数字比较用-eq,字符串才用==  
then
    # 这里才是执行区
fi

??救命口诀??:

  • 中括号内侧必须留空格,像对待前任的界限感
  • 数字用-eq,字符串用=
  • 变量最好加双引号,防止空格捣乱

上周帮学弟改代码,发现他把[ ]写成[[ ]]还奇怪为啥报错...(这两种括号的差别咱们后面细说)


场景二:权限不够的尴尬

??报错提示??:"Permission denied"
写了个超棒的脚本,执行时却像被门卫拦在门外?试试这个诊断流程:

bash复制
ls -l my_script.sh  # 查看文件权限
# 输出显示-rw-r--r-- 表示没有执行权限  
chmod +x my_script.sh  # 添加执行权限

??权限三连问??:

  1. 脚本开头有没有#!/bin/bash
  2. 是不是用Windows编辑的脚本?(换行符问题会导致神秘报错)
  3. 文件路径写的是绝对路径还是相对路径?

曾经有个兄弟死活运行不了脚本,最后发现他把脚本放在/tmp目录——这个文件夹默认有特殊权限限制,你说坑不坑?


场景三:变量消失魔术

??离奇现象??:

bash复制
name="老王"
echo $nmae  # 输出空行

??调试锦囊??:

  1. 在脚本开头加set -u,遇到未定义变量立即报错
  2. ${变量名}代替$变量名,清晰看到变量边界
  3. 复杂脚本建议先用bash -n 脚本名做语法预检

推荐个神器——VS Code安装ShellCheck插件,它能像语文老师一样揪出你的语法错误。之前有个脚本死活查不出问题,结果这工具一秒就提示我if后面多打了个分号。


场景四:管道操作吃数据

??诡异报错??:while read line循环只执行一次
看这段问题代码:

bash复制
cat file.txt | while read line
do
    echo $line
done
echo "总行数:${#line[@]}"  # 这里永远显示0

??真相揭秘??:管道会创建子进程,导致父进程拿不到变量值
??解决方案??:

bash复制
while read line
do
    # 处理逻辑
done < file.txt  # 改用输入重定向

这个坑有多深?某电商团队曾经因此统计错百万级订单数据,差点引发重大事故。


场景五:路径迷宫

??经典错误??:No such file or directory
你以为的当前目录≠脚本认为的当前目录!记住这两个黄金命令:

bash复制
# 获取脚本真实路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# 切换工作目录
cd "$SCRIPT_DIR" || exit 1

??避坑指南??:

  • 所有文件路径都用绝对路径
  • 涉及文件操作的先检查存在性:[ -f "文件" ] || exit
  • realpath命令解析路径(需要提前安装)

见过最离谱的案例:有人在脚本里写rm -rf $HOME/project/$VERSION/*,结果变量没赋值直接清空用户目录...(所以千万要做参数检查!)


个人观点

调试脚本就像破案,报错信息就是线索。刚开始可能会被syntax error气到砸键盘,但积累20个常见错误案例后,你会发现排查速度能提升10倍不止。记住:每个报错都是系统在给你划重点,耐心点,它正在教你成为真正的Shell高手。

(某位不愿透露姓名的运维工程师透露,掌握这些调试技巧后,他处理工单的时间从日均3小时降到20分钟——这大概就是传说中的"经验碾压"吧?)

本文由嘻道妙招独家原创,未经允许,严禁转载