快捷搜索:   nginx

Linux Shell 脚本调试技术(2)


17       #do something


18   fi




首先执行sh –n exp4.sh来进行语法检查,输出如下:



$ sh –n exp4.sh


exp4.sh: line 6: syntax error near unexpected token `else'


exp4.sh: line 6: `    else'




发现了一个语法错误,通过仔细检查第6行前后的命令,我们发现是第4行的if语句缺少then关键字引起的(写惯了C程序的人很容易犯这个错误)。我们可 以把第4行修改为if [ "$UID" -ne 0 ]; then来修正这个错误。再次运行sh –n exp4.sh来进行语法检查,没有再报告错误。接下来就可以实际执行这个脚本了,执行结果如下:



$ sh exp4.sh


exp2.sh: line 11: [1: command not found


welcome root user




尽管脚本没有语法错误了,在执行时却又报告了错误。错误信息还非常奇怪“[1: command not found”。现在我们可以试试定制$PS4的值,并使用“-x”选项来跟踪:



$ export PS4='+{$LINENO:${FUNCNAME[0]}} '


$ sh –x exp4.sh


+{10:} isRoot


+{4:isRoot} '[' 503 -ne 0 ']'


+{5:isRoot} return 1


+{11:} '[1' -ne 0 ']'


exp4.sh: line 11: [1: command not found


+{16:} echo 'welcome root user'


welcome root user




从输出结果中,我们可以看到脚本实际被执行的语句,该语句的行号以及所属的函数名也被打印出来,从中可以清楚的分析出脚本的执行轨迹以及所调用的函数的内 部执行情况。由于执行时是第11行报错,这是一个if语句,我们对比分析一下同为if语句的第4行的跟踪结果:



+{4:isRoot} '[' 503 -ne 0 ']'


+{11:} '[1' -ne 0 ']'




可知由于第11行的[号后面缺少了一个空格,导致[号与紧挨它的变量$?的值1被shell解释器看作了一个整体,并试着把这个整体视为一个命令来执行, 故有“[1: command not found”这样的错误提示。只需在[号后面插入一个空格就一切正常了。



shell中还有其它一些对调试有帮助的内置变量,比如在Bash Shell中还有BASH_SOURCE, BASH_SUBSHELL等一批对调试有帮助的内置变量,您可以通过man sh或man bash来查看,然后根据您的调试目的,使用这些内置变量来定制$PS4,从而达到增强“-x”选项的输出信息的目的。





五. 总结



现在让我们来总结一下调试shell脚本的过程:


首先使用“-n”选项检查语法错误,然后使用“-x”选项跟踪脚本的执行,使用“-x”选项之前,别忘了先定制PS4变量的值来增强“-x”选项的输出信 息,至少应该令其输出行号信息(先执行export PS4='+[$LINENO]',更一劳永逸的办法是将这条语句加到您用户主目录的.bash_profile文件中去),这将使你的调试之旅更轻松。 也可以利用trap,调试钩子等手段输出关键调试信息,快速缩小排查错误的范围,并在脚本中使用“set -x”及“set +x”对某些代码块进行重点跟踪。这样多种手段齐下,相信您已经可以比较轻松地抓出您的shell脚本中的臭虫了。如果您的脚本足够复杂,还需要更强的调 试能力,可以使用shell调试器bashdb,这是一个类似于GDB的调试工具,可以完成对shell脚本的断点设置,单步执行,变量观察等许多功能, 使用bashdb对阅读和理解复杂的shell脚本也会大有裨益。关于bashdb的安装和使用,不属于本文范围,您可参阅http: //bashdb.sourceforge.net/上的文档并下载试用。

顶(0)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论