jim*_*gee 8 bash debugging shell-script
我有一个 bash 脚本,目前有 700 多行。经过特别长时间的编辑,它现在出现如下错误:
./run_me.sh: line 693: unexpected EOF while looking for matching `''
./run_me.sh: line 702: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
但是,我可以看到第 693 行没有任何问题。它甚至没有引用。
我试过运行bash -x run_me.sh,并且可以看到最后一行运行,但该行也没有任何问题(该行和 693 之间的代码实际上是大部分代码)。
我可以注释掉整个代码,但是我更有可能看到由于缺少函数等而导致的错误,而不是我得到的 EOF 错误。
那么如果行号报告不正确,人们应该如何找到丢失的报价?
(无论如何,为什么 bash 的行号报告如此遥远?)
顺便说一句,我发现了我的特定错误(通过评论条带),这实际上是}在任意行号处的变量扩展中缺少错误消息指示的行——基于引号的语法突出显示在这里没有帮助,例如"${MY_ARRAY[@]"(应该是"${MY_ARRAY[@]}")中缺少的大括号。
一种低技术的方法是
tr -cd "'\n" < run_me.sh | awk 'length%2==1 {print NR, $0}'
Run Code Online (Sandbox Code Playgroud)
在tr除了单引号和换行符,并且删除所有字符awk识别具有字符(即,非匹配引号)的奇数行。单独检查它们;请注意,像这样的有效字符串"That's not a bug!"将被标记。
如果这不能突出问题,请再试一次tr -cd '"\n'
(以查找不匹配的双引号)。
接下来,展开tr允许(),[]并最终{}
要经过。在这一点上,对输出的人工检查变得不那么富有成效;而(与)通常在同一行内匹配,报价和方括号几乎总是,这不是真正的{和 }。(但是,寻找不匹配{并 }
会发现 OP 实际存在的问题,即键入"${MY_ARRAY[@]"而不是 )。"${MY_ARRAY[@]}"
如果您已将问题缩小到花括号不匹配,特别是如果您缩小了文件中的范围,请转到计划 B。在vim(或vi)中打开文件。转到{您认为在错误之前的字符并键入%。如果光标跳到}
您认为与{您开始时匹配的位置,请移至下一个{并重复。如果它跳转到}与{您开始的不匹配的a ,则这两个大括号之间会发生错误。如果它不移动,则错误发生在您的当前位置和文件末尾之间。放大。
这种方法可能稍微更适合于使用 C、C++ 和 Java 等语言编写的程序文件(如果它们的编译器做得不够好),但它对于 shell 脚本应该工作得相当好。
像ShellCheck这样的外部linting工具可以检测问题,并且可能有比bash它自己更好的消息和位置。
对于主要是中间echo带有 a 的语句的程序"${MY_ARRAY[1]",ShellCheck 会告诉您它无法解析带引号的字符串。它甚至将问题归结为$字符并暗示参数扩展有问题。
ShellCheck 与 Vim、Emacs、SublimeText 和 Atom(以及其他)一起使用。
最简单的方法?使用带有语法着色的编辑器,该编辑器了解您正在使用的外壳,并进行可视化检查。当你得到一大片字符串颜色时,你知道你遗漏了一个引号。几乎任何像样的编程编辑器都有语法着色。
语法着色有时会出错,但这通常表明您的程序过于复杂,人类也可能会出错。
对于shell编程,确保使用的字体在那里",'并且`很容易分辨。检查您是否无意中使用了看起来像 ASCII 引号的非 ASCII 字符,例如‘’“”.