shell 调试手段总结

对于厌烦了的 print 和 echo,可以尝试点新鲜省力的小手段。

1. 使用 shell 的执行选项

sh 和 bash 常用的执行指令有:-n、-x、-c、-v。

其中:

-n 是 noexec 的简写,作用是只做脚本的语法检查,而不执行脚本。

-x 是 xtrace 的简写,作用是在每一行代码执行之前,将代码本身打印到标准输出(代码前添加一个 “+” 用来区别)。这个在调试的时候尤其有用。

-c 是 command string 的缩写,使用该选项从字符串而不是文件读取脚本。比如,sh -c 'a=1;b=2;let c=$a+$b;echo "c=$c"'。

-v 是 verbose 的缩写,用来显示所有读入的标准输入

这些选项除了在启动脚本时指定外,我们还可以在脚本中,使用 set 来设置。比如,在脚本中,我们可以用 set 来打开和关闭 xstrace

set -x    #启动"-x"选项 
要跟踪的程序段 
set +x     #关闭"-x"选项

 

2. 用 trap 设置调试陷阱

trap 是可以接收指定的 SIGNAL ,然后,执行设定的脚本。除了我们使用 kill -l 罗列的那些 SIGNAL,还有三个虚拟的 SIGNAL:EXIT,ERR,DEBUG。前两个不必说,第三个是每执行一条指令都会发出的。。。所以,我们可以借助 DEBUG 来跟踪变量。如下,我们可以在脚本中添加这么一行代码:

trap 'echo "line:$LINENO, a=$a"' DEBUG

然后,脚本每执行一行,都会打印相应行号,以及 a 的值。。。当然,除了变量 a ,你可以随意指定要要追中的变量。比如,下面这个例子:

 1 #!/bin/bash
 2 
 3 trap 'echo "line:$LINENO, str=$str, str1=$str1"' DEBUG
 4 
 5 str="abcdefg"
 6 
 7 str1=$(expr substr "$str" 1 3)
 8 
 9 echo $str1
10 
11 if [ $str1 == "abc" ] ;then
12     echo "nice"
13 fi

执行的结果如下:

line:5, str=, str1=
line:7, str=abcdefg, str1=
line:9, str=abcdefg, str1=abc
abc
line:11, str=abcdefg, str1=abc
line:12, str=abcdefg, str1=abc
nice

主意,因为这里只有 5、7、9 、11、12 这几行有代码,所以~

 

3. 用 tee 来调试管道

有时候我们需要调试管道。。。比如下面这条,套了好几层,也不知道谁对谁错。。。一条条的试?好像也比较麻烦。

tee 的作用呢,是当标准输入有数据时,把数据转到标准输出的同时,把数据写到某文件中。比如:

ipaddr=`/sbin/ifconfig | grep 'inet addr:' | grep -v '127.0.0.1'
| tee temp.txt | cut -d : -f3 | awk '{print $1}'`
echo $ipaddr

tee 这一段,完全就是为了查看中间输出了什么。。。执行完这一句,在当前目录多了一个 temp.txt 的文件,内容是:

$ cat temp.txt
inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0

so...

 

4. 使用调试钩子

这个完全就是用普通代码完成的小技巧,相信其他语言编程的时候,这样的代码也常用的。在 shell 中实现出来大概是这样的:

if [ “$DEBUG” = “true” ]; then
echo “debugging”  #此处可以输出调试信息
fi

用这段代码,我们可以方便的用一个名为 DEBUG 的变量控制是否输出调试信息;设置 'export DEBUG=true' 就可以打开调试输出或者,我们可以定一个 DEBUG 函数

DEBUG()
{
    if [ "$DEBUG" = "true" ]; then
        $@  
    fi
}

a=1
DEBUG echo "a=$a"

if [ "$a" -eq 1 ] ;then
    b=2
else
    b=1
fi

DEBUG echo "b=$b"
c=3
DEBUG echo "c=$c"

 发布的时候,记得把调试开关关了,留着代码,也没多大影响。

你可能感兴趣的:(shell 调试手段总结)