问题背景
编写完一个脚本之后,就要第一次运行它了。但是,如果在执行脚本时显示某些意外的错误,应该怎么办呢?没有人是完美的,而且从头编写脚本并保持没有错误需要大量时间和丰富的经验;大多数时候,开发人员很容易漏掉一个字母或者颠倒了两个字母的顺序,这几乎是不可避免的。不必担心:Linux 中的 shell 已经考虑到了这个问题,可以帮助您进行调试。
例如,清单 1 中的 shell 脚本(名为 make_errors)已经编写好等待执行。
清单 1:包含错误的脚本示例
#!/bin/bash
_X=1
while [[ ${_X} -le 10 ]]
do
[[ ${_X} -lt 5 ]] && echo "X is less than 5!
_Y=`expr ${_X) + 1`
if [[ ${_Y} -eq 6 ]]
echo "Y is now equal to ${_Y}"
fi
_X=${_Y}
done
初次执行这个脚本时,显示以下错误:
# ./make_errors
./make_errors: line 8: unexpected EOF while looking for matching `"'
./make_errors: line 12: syntax error: unexpected end of file
VIM 是一种出色的调试工具,您可能使用过它,但不一定了解它的真正价值。Vim 是一种强大的文本编辑器,但是它对调试也很有帮助。如果通过设置 .vimrc 文件指定用不同的颜色显示某些错误,Vim 就会替您完成大部分调试工作。
用 VIM进行调试
第一个错误消息(line 8: unexpected EOF while looking for matching `"')指出在第 8 行上有错误,但是看过这一行之后,并没有发现任何错误。再看看第 5 行,发现echo
后面的字符串的末尾缺少一个双引号"。这个示例很好地说明了在进行调试时为什么必须查看整个脚本。也就是说错误消息中显示的行号不一定是出现错误的实际位置。
报告第 8 行有错误是因为第 5 行用双引号标出一个字符串的开头,但是这个字符串直到第 8 行才结束。要想纠正这个错误,应该在第 5 行末尾添加双引号。
其他一些问题也会显示为错误。在第 6 行上,变量值 _X 后面是一个用红色突出显示的后圆括号)。这是 VIM 替您做出的判断,它指出这里有错误。这里用一个左花括号 { 标出了变量值 _X 的开头,但是没有用右花括号 } 结束。所以只需把 ) 改为
},就能够纠正这个错误。
到目前为止,已经纠正了两个错误。再次运行这个脚本,看看会发生什么:
# ./make_errors
line 9: syntax error near unexpected token `fi'./make_errors: line 9: ` fi'
还有另一个错误,错误消息指出问题出现在第 9 行上,但是这一行只有一个用来结束 if 语句的
fi。这有什么错呢?请牢记前一个错误的情况。并非所有错误都源自 shell 所报告的行上。shell
仅仅报告发生错误的位置,但是错误的根源可能出现在这个位置之前。对于这个小脚本,可以很有把握地猜测错误可能出现在实际的 if
语句中。回忆一下基本的脚本编程逻辑:if 语句由 if、then 和 fi 组成。看看这个条件语句,可以看出缺少了 then。只需在脚本中添加
then。完成之后,这个脚本应该类似于清单 2。
清单 2:纠正清单 1 中的所有错误之后的正确脚本
#!/bin/bash
_X=1
while [[ ${_X} -le 10 ]]
do
[[ ${_X} -lt 5 ]] && echo "X is less than 5!"
_Y=`expr ${_X} + 1`
if [[ ${_Y} -eq 6 ]];then
echo "Y is now equal to ${_Y}"
fi
_X=${_Y}
done
再次运行这个脚本:
# ./make_errors
X is less than 5!
X is less than 5!
X is less than 5!
X is less than 5!
Y is now equal to 6
恭喜!这个脚本现在正常工作了!
结束语
无论是使用 shell 脚本、C、Java或其他语言,我们都在不断地改进编程方法,坚持简单化的基本规则,保持代码简洁灵活,给代码加上适当的注释,再借助调试工具的帮助,您很快就能编写出出色的 shell 脚本。