-x 是
set
命令中的一个选项,它用来
进入跟踪方式,这样会显示出脚本执行每一条命令及其参数,它是脚本调试中的一个有用选项。它输出的被执行的命令行及参数前面会添加一个 "+" 号。实际上,这个 "+" 号就是内置变量 $PS4 的值,可以输出验证:
我们可以对 -x 选项,或者说是 $PS4 这个变量进行扩展,使调试功能得到增强。以调试下面一段代码为例:
调试这段脚本时,先使用普通的运行方式: 第 7 行发生语法错误,这里的 if 漏掉了 then 语句,修正后再次运行:
第 14 行发出命令找不到的错误。这是怎么回事呢?用 set 命令的 -x 选项,再配合 $LINENO 和 $FUNCNAME 内置变量来跟踪这个问题。首先对 $SP4 变量进行设置:
然后以带有 -x 选项的方式运行脚本:
找到 14 行这里,原来 shell 将 [500 当成是一个命令了。比较脚本代码时可以看到第 14 行中左中括号和 $? 之间没有空格,所以脚本在展开时被写成 [500 ,这样就被 shell 当作一个整体进行解释,而一个整体在 shell 中是要被解释为命令的。所以在 [ 和 $? 之间加上一个空格即可解决这个错误。
$LINENO 表示脚本执行到的当前行,这和 C语言 中的内置宏 __LINE__ 是一个道理。
$FUNCTION 也是一个内置变量,它相当于 C语言 中的内置宏 __func__ 。但 $FUNCTION 它比 __func__ 更强大,它实际上是一个数组变量,如同堆栈一般,在栈底的是脚本的顶层"main",在栈顶的是当前所执行的函数,所以 $[FUNCTION[0]} 就是要显示出当前的执行函数。
所以使用 -x ,$LINENO 以及 $FUNCNAME 配合使用,可以在调试脚本时跟踪脚本的执行流程及轨迹。
我们可以对 -x 选项,或者说是 $PS4 这个变量进行扩展,使调试功能得到增强。以调试下面一段代码为例:
[Bash shell]
syntaxhighlighter_viewsource
syntaxhighlighter_copycode
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#!/bin/bash
checkname()
{
if
[
"$USER"
=
"beyes"
];
then
return
0
else
return
1
fi
}
checkuid()
{
if
[
"$UID"
-
eq
500 ];
then
return
0
else
return
1
fi
}
checkname
if
[
"$?"
-
eq
0 ];
then
echo
"check name ok!"
else
echo
"check name failed"
fi
checkuid
if
[
"$?"
-
eq
0 ];
then
echo
"check uid ok!"
exit
0
else
echo
"check uid failed"
exit
1
fi
|
调试这段脚本时,先使用普通的运行方式: 第 7 行发生语法错误,这里的 if 漏掉了 then 语句,修正后再次运行:
第 14 行发出命令找不到的错误。这是怎么回事呢?用 set 命令的 -x 选项,再配合 $LINENO 和 $FUNCNAME 内置变量来跟踪这个问题。首先对 $SP4 变量进行设置:
然后以带有 -x 选项的方式运行脚本:
找到 14 行这里,原来 shell 将 [500 当成是一个命令了。比较脚本代码时可以看到第 14 行中左中括号和 $? 之间没有空格,所以脚本在展开时被写成 [500 ,这样就被 shell 当作一个整体进行解释,而一个整体在 shell 中是要被解释为命令的。所以在 [ 和 $? 之间加上一个空格即可解决这个错误。
$LINENO 表示脚本执行到的当前行,这和 C语言 中的内置宏 __LINE__ 是一个道理。
$FUNCTION 也是一个内置变量,它相当于 C语言 中的内置宏 __func__ 。但 $FUNCTION 它比 __func__ 更强大,它实际上是一个数组变量,如同堆栈一般,在栈底的是脚本的顶层"main",在栈顶的是当前所执行的函数,所以 $[FUNCTION[0]} 就是要显示出当前的执行函数。
所以使用 -x ,$LINENO 以及 $FUNCNAME 配合使用,可以在调试脚本时跟踪脚本的执行流程及轨迹。