项目场景:
新手 shell 程序员初次写 bash 脚本时,难免出现各种各样的错误,有时也只能使用费时费力的打印调试定位问题。其实可以使用 shell bash 自带的调试选项,才方便地定位问题和调试。
知识铺垫:
带 -n 选项的 bash 命令,能够对脚本进行语法检查,而不去实际运行其中的任何一条命令。如果脚本中存在语法错误, shell 就会报错。如果没有错误,shell 就不显示任何内容。
最常用的脚本调试手段是用带 -x 选项的 set 命令,或是调用带 -x 选项和脚本名为参数的 bash。调试选项列表见下表。这些选项能使您跟踪脚本的执行。此时,shell 脚本中每条命令的处理过程是:先执行替换,接着显示,然后再执行它。 shell 显示脚本中的行时,会在行首添上一个加号(+)。
命令 | 选项 | 功能 |
---|---|---|
bash -x 脚本名 | Echo 选项 | 在变量替换之后、执行命令之前,显示脚本的每一行 |
bash -v 脚本名 | Verbose 选项 | 在执行之前,按输入的原样打印脚本中各行 |
bash -n 脚本名 | Noexec 选项 | 解释但不执行命令 |
set -x | 打开 echo | 跟踪脚本的执行 |
set +x | 关闭 echo | 关闭跟踪功能 |
示例1:
(脚本)
#! /bin/bash
# Scriptname: todebug
name="Joe Shmoe"
if [[ $name == "Joe Blow" ]]
then
printf "Hello $name\n"
fi
declare -i num=1
while (( num < 5 ))
do
let num+=1
done
printf "The total is %d\n" $num
(命令)
[root@localhost tmp]# bash -x todebug
+ name='Joe Shmoe'
+ [[ Joe Shmoe == \J\o\e\ \B\l\o\w ]]
+ declare -i num=1
+ (( num < 5 ))
+ let num+=1
+ (( num < 5 ))
+ let num+=1
+ (( num < 5 ))
+ let num+=1
+ (( num < 5 ))
+ let num+=1
+ (( num < 5 ))
+ printf 'The total is %d\n' 5
The total is 5
说明:
1.该脚本名为 todebug。可以通过打开 -x 开关来观察脚本的运行。循环的每一次遍历都显示在屏幕上,变量每次被设置和修改后,其值也被打印出来。
2.带 -x 选项启动 Bash shell。显示选项被打开,脚本的每一行都被显示在屏幕上,行首增加了一个加号(+)。变量替换在显示之前执行。在显示的命令行的后面,打印命令的执行结果。
示例2:
eval命令处理命令行,先执行所有的 shell 替换,然后执行命令行。当通常的命令行解析无法满足要求时,就要使用 eval 命令。
[root@localhost ~]$ help eval
eval: eval [arg ...]
Execute arguments as a shell command.
Combine ARGs into a single string, use the result as input to the shell,
and execute the resulting commands.
Exit Status:
Returns exit status of command or success if command is null.
1 [root@localhost tmp]# set a b c d
2 [root@localhost tmp]# echo The last argument is \$$#
3 The last argument is $4
[root@localhost tmp]#
4 [root@localhost tmp]# eval echo The last argument is \$$#
The last argument is d
[root@localhost tmp]#
5 [root@localhost tmp]# set -x
[root@localhost tmp]# eval echo The last argument is \$$#
+ eval echo The last argument is '$4'
++ echo The last argument is d
The last argument is d
[root@localhost tmp]#
说明:
- 设置 4 个位置参量。
- 用户希望得到的结果是显示最后一个位置参量的值。\$打印出一个美元符。$# 的值是4,即位置参量的个数。shell 求出 $# 的值后,不会再次解析命令行以得出 $4的值。
- 显示的结果是 $4,而不是最后那个参数。
- shell 执行完所有的变量替换后,eval 命令又执行一次变量替换,然后执行 echo 命令。
- 打开反显选项来观察解析的顺序。