我们写的Shell脚本很少能一次就写好,没有任何问题。程序写好后都需要调试,找出存在的问题。Shell脚本调试的方法有:
1. 注释掉部分代码
利用注释调试适用于所有的编程语言。如果怀疑某部分代码有问题,可以将其注释掉,若问题消失,就能定位到出问题的位置。
2. 输出跟踪变量值
这也是常用的程序调试方法。通过输出变量值,判断该部分运行是否正常。echo是最常用的输出命令,另外也可以利用tee命令同时输出到文件和标准输出。tee命令就像接自来水管的三通一样,它会把输出内容复制一份并重定向到文件,原来的内容继续输出到标准输出。下面的例子显示的是tee的用法:
[peter@ibi98 tee]$ echo "Arabidopsis thaliana" |tee species Arabidopsis thaliana [peter@ibi98 tee]$ ls species [peter@ibi98 tee]$ cat species Arabidopsis thaliana
tee命令后面,标准输出仍然有内容,同时文件species中也有了同样的内容。
3. 使用trap命令
trap命令可以指定在接收到信号后要执行的命令,常用于在脚本程序被中断时完成清理工作。如:
trap "echo Terminated; rm tmp_files" INT
把程序中加上面的代码,如果在执行过程中用户按了Ctrl+c,则程序会显示Terminated,然后删除tmp_files并退出。
[peter@ibi98 set]$ cat test.sh #!/bin/bash while true #条件永远成立,一直执行下面的循环,直到被中断 do trap "echo Terminated; exit" SIGINT #捕捉到中断信号后输出Terminated,然后退出 done [peter@ibi98 set]$ sh test.sh ^CTerminated
下表是常用的信号,使用kill -l命令可以显示所有信号。
HUP(1) 挂起,通常因终端掉线或用户退出而引发 INT(2) 中断,通常因按下Ctrl+C组合键而引发 QUIT(3) 退出,通常因按下Ctrl+\组合键而引发 ABRT(6) 中止,通常因某些严重的执行错误而引发 ALRM(14) 报警,通常用来处理超时 TERM(15) 终止,通常在系统关机时发送
4. 利用Shell脚本调试选项
Shell与调试有关的选项有:-c、-n、-v、-x。
-c 使Shell解析器从字符串而非文件中读取并执行命令 -n 读一遍脚本中的命令但不执行,用于检查脚本中的语法错误 -v 一边执行脚本,一边将执行过的脚本命令打印到标准错误输出 -x 提供跟踪执行信息,将执行的每一条命令和结果依次打印出来
bash使用-c选项后,功能类似perl的命令行用法。-c选项的使用方法如下:
[peter@ibi98 shell]$ sh -c 'let x=5;y=3;let sum=x+y;echo $sum'
8
-v选项在执行每一条命令前,打印命令行的原始内容并输出到标准错误输出。
-x选项提供跟踪执行信息,将脚本执行过程中实际执行的每个命令显示出来,行首显示+,+后面显示经过替换之后的命令行内容,有助于分析实际执行的是什么命令,如设置-x选项后,ls命令的结果前会显示:+ ls --color=auto,也就是你输入的ls命令,实际上执行的是ls --color=auto,因为通常用的ls实际上是ls --color=auto的别名,你用type ls就可以看到。
有三种方法使用Shell调试选项:
(1)命令行参数
[peter@ibi98 shell]$ sh -n hello.sh
(2)在脚本开头提供参数
[peter@ibi98 shell]$ cat hello.sh #!/bin/bash -v echo "Hello world!" [peter@ibi98 shell]$ ./hello.sh #!/bin/bash -v echo "Hello world!" #输出结果前先打印命令的原始内容 Hello world! #命令输出结果
(3)脚本中用set命令设定
[peter@ibi98 set]$ ls test.sh [peter@ibi98 set]$ set -x #为当前Shell设置-x选项 ++ printf '\033]0;%s@%s:%s\007' peter ibi98 '~/shell/set' #打印命令提示行 [peter@ibi98 set]$ ls + ls --color=auto #执行命令前先打印实际执行的命令(替换后的命令) test.sh ++ printf '\033]0;%s@%s:%s\007' peter ibi98 '~/shell/set' #打印命令提示行 [peter@ibi98 set]$ set +x #取消-x选项 + set +x [peter@ibi98 set]$ ls test.sh
-v和-x用来跟踪命令及其输出,从而找出出问题的代码。
5. 使用Bash专用调试器
Bash程序可以用专用的调试工具如bashdb进行调试,感兴趣的可以自己学习一下。
Shell脚本语法要求比较严格,刚开始学习有点不适应。一旦掌握了Shell语法的规律,加上上面的几种调试方法,写一个功能强大的Shell脚本将不是难事。