LinuxShell脚本执行流程_调试与排错说明【指导】

19次阅读

“command not found”主因是PATH不含当前目录或缺少执行权限;需chmod +x并用./运行;shebang应优先用#!/usr/bin/env bash;注意等号无空格、避免windows换行符、子shell不继承变量。

LinuxShell脚本执行流程_调试与排错说明【指导】

脚本执行时直接报错“command not found”

这通常不是语法问题,而是 PATH 没包含当前目录,或脚本没加执行权限。linux 默认不把 .(当前目录)加入 PATH,所以不能直接敲 myscript.sh 运行。

  • 确认权限:chmod +x myscript.sh,否则即使有 shebang 也执行不了
  • 运行方式优先用 ./myscript.sh,而非 myscript.sh
  • 如果用了 #!/bin/bash 但系统实际是 /usr/bin/bash,可能报错;可用 #!/usr/bin/env bash 更兼容
  • 检查 shebang 行末是否混入 windows 换行符(^M),用 dos2unix myscript.shsed -i 's/r$//' myscript.sh 清理

变量未生效或值为空,但看起来写对了

Bash 中变量赋值等号两侧**不能有空格**,且子 shell 不继承父 shell 变量——这是最常被忽略的根源。

  • 错误写法:FOO = "bar" → 正确是 FOO="bar"
  • 管道会创建子 shell:echo "a b" | while read x; do echo $x; done 中的 $x循环外不可见;改用 while read x; do ...; done 或重定向避免
  • 导出变量需显式 export VAR,否则 source. 加载的脚本里定义的变量不会传给后续命令
  • 引用变量建议统一用 "$VAR",避免空格或通配符引发意外分词

用 set -x 调试却看不懂输出

set -x(或 bash -x script.sh)会打印每条执行前的展开结果,但容易混淆“原始语句”和“实际执行内容”。

  • 在脚本开头加 set -x,结尾加 set +x 控制范围;不要全脚本开启
  • 注意引号影响:比如 echo "$HOME/*"echo $HOME/* 展开后完全不同,set -x 显示的是后者已 glob 展开的结果
  • 调试函数时,set -x 会显示函数名+参数,但不会显示函数内局部变量(除非手动 declare -p
  • 临时加 echo "DEBUG: var=$VAR" 比纯 set -x 更精准,尤其涉及复杂字符串拼接或条件分支时

if 判断总走错分支,[ ] 和 [[ ]] 混用出问题

[ ] 是 POSIX 兼容的外部命令(常为 /bin/[),而 [[ ]] 是 Bash 内建关键字,行为差异大,混用极易翻车。

  • [ $VAR = "val" ] 中若 $VAR 为空,实际变成 [ = "val" ] → 语法错误;必须写成 [ "$VAR" = "val" ]
  • [[ $VAR =~ ^[0-9]+$ ]] 支持正则,但 [ ] 不支持;[[ ]]=~ 左侧变量无需引号,右侧模式也不能加引号
  • [[ ]] 支持 ==(等价于 =)和通配符匹配,[ ] 只认 = 且不支持通配符
  • 跨 shell 移植性要求高时用 [ ],但务必加引号;仅 Bash 环境下推荐统一用 [[ ]] 并关闭 set -o nounset 配合防御性检查
#!/bin/bash set -euo pipefail # -e:任一命令失败即退出;-u:引用未定义变量报错;-o pipefail:管道中任一环节失败整个管道失败 # 这三者组合能暴露多数隐性错误,比单靠 set -x 更早发现问题

真正卡住的往往不是语法,而是子 shell 边界、变量作用域、以及不同 test 形式对空值/特殊字符的容忍度——这些地方不打日志、不看展开结果,光读代码根本看不出问题。

text=ZqhQzanResources