当事情没有按计划进行时,你需要确定到底是什么导致脚本失败。Bash 提供了广泛的调试功能。最常见的是使用以下选项启动子 shell:-x选项,它将以调试模式运行整个脚本。每个命令及其参数的跟踪信息会在命令展开之后、执行之前打印到标准输出。
这是commented-script1.sh脚本在调试模式下运行的示例。再次注意,添加的注释在脚本的输出中是不可见的。
willy:~/scripts> bash -x script1.sh + clear + echo 'The script starts now.' The script starts now. + echo 'Hi, willy!' Hi, willy! + echo + echo 'I will now fetch you a list of connected users:' I will now fetch you a list of connected users: + echo + w 4:50pm up 18 days, 6:49, 4 users, load average: 0.58, 0.62, 0.40 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root tty2 - Sat 2pm 5:36m 0.24s 0.05s -bash willy :0 - Sat 2pm ? 0.00s ? - willy pts/3 - Sat 2pm 43:13 36.82s 36.82s BitchX willy ir willy pts/2 - Sat 2pm 43:13 0.13s 0.06s /usr/bin/screen + echo + echo 'I'\''m setting two variables now.' I'm setting two variables now. + COLOUR=black + VALUE=9 + echo 'This is a string: ' This is a string: + echo 'And this is a number: ' And this is a number: + echo + echo 'I'\''m giving you back your prompt now.' I'm giving you back your prompt now. + echo |
现在有一个功能齐全的 Bash 调试器,可在 SourceForge 上获取。这些调试功能在大多数现代版本的 Bash 中都可用,从 3.x 版本开始。
使用 set Bash 内建命令,你可以对那些你确信没有错误的脚本部分以正常模式运行,而只对有问题的区域显示调试信息。假设我们不确定 w 命令在以下示例中会做什么commented-script1.sh,那么我们可以像这样在脚本中将其包围起来
set -x # activate debugging from here w set +x # stop debugging from here |
输出看起来像这样
willy: ~/scripts> script1.sh The script starts now. Hi, willy! I will now fetch you a list of connected users: + w 5:00pm up 18 days, 7:00, 4 users, load average: 0.79, 0.39, 0.33 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root tty2 - Sat 2pm 5:47m 0.24s 0.05s -bash willy :0 - Sat 2pm ? 0.00s ? - willy pts/3 - Sat 2pm 54:02 36.88s 36.88s BitchX willyke willy pts/2 - Sat 2pm 54:02 0.13s 0.06s /usr/bin/screen + set +x I'm setting two variables now. This is a string: And this is a number: I'm giving you back your prompt now. willy: ~/scripts> |
你可以在同一个脚本中多次打开和关闭调试模式。
下表概述了其他有用的 Bash 选项
表 2-1. set 调试选项概述
简写 | 完整写法 | 结果 |
---|---|---|
set -f | set -o noglob | 禁用使用元字符进行文件名生成(通配符展开)。 |
set -v | set -o verbose | 打印读取的 shell 输入行。 |
set -x | set -o xtrace | 在执行命令之前打印命令跟踪。 |
短划线用于激活 shell 选项,加号用于停用它。不要被这个搞糊涂了!
在下面的示例中,我们在命令行上演示这些选项
willy:~/scripts> set -v willy:~/scripts> ls ls commented-scripts.sh script1.sh willy:~/scripts> set +v set +v willy:~/scripts> ls * commented-scripts.sh script1.sh willy:~/scripts> set -f willy:~/scripts> ls * ls: *: No such file or directory willy:~/scripts> touch * willy:~/scripts> ls * commented-scripts.sh script1.sh willy:~/scripts> rm * willy:~/scripts> ls commented-scripts.sh script1.sh |
或者,这些模式可以在脚本本身中指定,通过将所需的选项添加到第一行 shell 声明中。选项可以组合使用,这通常是 UNIX 命令的惯例
#!/bin/bash-xv
一旦你找到了脚本中出错的部分,你可以在每个你不确定的命令之前添加 echo 语句,这样你就可以确切地看到哪里出了问题以及为什么会出错。在示例commented-script1.sh脚本中,可以这样做,仍然假设显示用户给我们带来了问题
echo "debug message: now attempting to start w command"; w |
在更高级的脚本中,可以插入 echo 来显示脚本中不同阶段的变量内容,以便检测缺陷
echo "Variable VARNAME is now set to $VARNAME." |