HP-UX环境下Shell程序调试实验教程
本教程(严格说起来算不上一个教程)所有实例和方法在HP-UX11.00(L2000)通过。对于其它的UNIX平台或SHELL,做相应调整即可。本教程旨在教你如何调试你的Shell程序,不涉及Shell编程的其它知识和技巧。有任何问题请不要hesitate to给我发邮件:hpux@vip.sina.com !
先照着输入这个小程序,判断当前的SHELL是不是sh(HP-UX默认的Shell是sh):
#vi getsh.sh
[color=red:c35801b851]#!/usr/bin/sh
curr_sh=`ps|grep $$|awk ‘{print $4}’`
if [ curr_sh=”sh” ]
echo “The current shell is sh.”
else
echo “The current shell isn’t sh.”
fi[/color:c35801b851]
首先我们让它可执行:
#chmod 755 getsh.sh
第一步,你必须测试有没有语法错误,而且你也可以立即测试了:
#./getsh.sh
[color=blue:c35801b851]./getsh.sh[3]: syntax error at line 6: ‘else’ unexpected[/color:c35801b851]
通过实际运行的系统错误提示,你知道了是if语句出问题了。
可是,你不应该这么做!假如这个shell是和系统有关,比如涉及到修改系统核心参数、涉及到删除备份文件等,就不能通过这种方式来调试语法了。大部分的Shell都提供一个-n参数,作用是仅仅读入脚本而不实际运行。比如,你现在想调试getsh.sh,那么你可以这样:
#/usr/bin/sh –n ./getsh.sh
[color=blue:c35801b851]./getsh.sh[3]: syntax error at line 6: ‘else’ unexpected[/color:c35801b851]
一样可以得到语法上的错误提示,而实际上这些脚本并不运行,是不是安全极了?如果你希望看到shell读入的每一行程序,还可以加上一个-v参数,比如:
#/usr/bin/sh –vn ./getsh.sh
[color=blue:c35801b851]#!/usr/bin/sh
curr_sh=`ps|grep $$|awk ‘{print $4}’`
if [ curr_sh=”sh” ]
echo “The current shell is sh.”
else
./getsh.sh[3]: syntax error at line 6: ‘else’ unexpected[/color:c35801b851]
可以看出,执行到else的时候就出错了!好象需要一个then哦……
那好,知道是if ..then…else..fi的问题,我们修改一下程序为:
[color=red:c35801b851]#!/usr/bin/sh
curr_sh=`ps|grep $$|awk ‘{print $4}’`
if [ curr_sh=”sh” ]
then
echo “The current shell is sh.”
else
echo “The current shell isn’t sh.”
fi[/color:c35801b851]
做语法检查:
#/usr/bin/sh –n ./getsh.sh
通过,耶!!!(当然,实际上可能你的shell程序非常长,调试了好几个小时或好几天,终于通过了才“耶”,否则,用这个字说明你太容易满足了,题外话,嘿嘿)
语法没问题了,是不是你的脚本就一点问题都没有了呢?当然不是。
#./getsh.sh
[color=blue:c35801b851]The current shell isn’t sh.[/color:c35801b851]
和你预计的结果有出入吧!
#ps|grep $$|awk ‘{print $4}’
[color=blue:c35801b851]sh[/color:c35801b851]
既然当前shell确实是sh,那么问题一定出在if语句上。好,现在就来进行shell的跟踪调试:
#vi ./getsh.sh
[color=red:c35801b851]#!/usr/bin/sh
curr_sh=`ps|grep $$|awk ‘{print $4}’`
set -x
if [ curr_sh=”sh” ]
then
echo “The current shell is sh.”
else
echo “The current shell isn’t sh.”
fi[/color:c35801b851]
注意程序增加了一行
set –x
这是打开shell跟踪模式的方法。如果没有set +x语句出现,那么脚本将按跟踪模式运行到结尾。一般都不希望这么做,而仅仅跟踪某一段程序。比如:
set –x
【要跟踪的程序段】
set +x
现在实际运行看看:
#./getsh.sh
[color=blue:c35801b851]+ [curr_sh = sh ]
+ echo The current shell isn’t sh.
The current shell isn’t sh.[/color:c35801b851]
这里,所有+开头的行都是shell真正执行了的命令,其它行是这些命令的输出。
看看都执行了什么?curr_sh=sh,怎么会出现这个比较啊?……$curr_sh……
于是改程序为:
[color=red:c35801b851]#!/usr/bin/sh
curr_sh=`ps|grep $$|awk ‘{print $4}’`
if [ $curr_sh=”sh” ]
then
echo “The current shell is sh.”
else
echo “The current shell isn’t sh.”
fi[/color:c35801b851]
再来:
#./getsh.sh
[color=blue:c35801b851]The current shell isn’t sh.[/color:c35801b851]
怪事!!!再认真确认100遍上面的程序,实在是找不出别的什么问题了。
还得求助于set –x,于是改程序为:
[color=red:c35801b851]#!/usr/bin/sh
curr_sh=`ps|grep $$|awk ‘{print $4}’`
set -x
if [ $curr_sh=”sh” ]
then
echo “The current shell is sh.”
else
echo “The current shell isn’t sh.”
fi[/color:c35801b851]
#./getsh.sh
[color=blue:c35801b851]+ [ getsh.sh = sh ]
+ echo The current shell isn’t sh.
The current shell isn’t sh.[/color:c35801b851]
当前Shell已经不是sh而是脚本文件getsh.sh,难怪!调试完成记得把set –x删除哦。
至此getsh.sh程序调试完毕,其中做了语法错误调试、逻辑错误调试和结果测试,算是基本完成了一个Shell要用到的所有调试步骤。对于一些很大的shell程序,可以在要调试的地方加入一个测试语句,比如:
if [ $SHELL_DEBUG = “scriptmustdebug” ]
then
set –x
fi
这样,要调试的时候,就设置SHELL_DEBUG = “scriptmustdebug”,调试完成,清除SHELL_DEBUG变量值即可,有些教材也把这种方法叫做“调试钩子“!
By hpux 2003.6.9
albert 回复于:2003-06-09 18:02:57 |
读后感: 很生动形象。
HPUX老大是不是老师出身啊? |
hpux 回复于:2003-06-09 18:32:30 |
其实这个教程是针对初学者的,不过对于一些高手但是不懂得调试shell时,也很有帮助。
大家学习方法即可! To albert兄,我不是教师出身啊,请多多指教。 |
leitianjun 回复于:2003-06-10 01:09:11 |
[img:ed1d763e68]http://bbs.zjcan.com/UploadFile/200351718018827.gif[/img:ed1d763e68]
学习中!!!!!!!! |
maqizhi 回复于:2003-06-11 09:36:37 |
长知识!好帖! |
blackwolfdog 回复于:2003-06-11 10:36:12 |
我在linux上作了一个试验,与你的输出不一样啊!
请解释 /home/oracle/lyc]more getsh.sh #!/bin/bash curr_sh=`ps|grep $$|awk '{print $4}'` echo $curr_sh if [ $curr_sh="sh" ] then echo "The current shell is sh." else echo "The current shell isn’t sh." fi echo $curr_sh /home/oracle/lyc] /home/oracle/lyc]./getsh.sh getsh.sh The current shell is sh. getsh.sh /home/oracle/lyc] 可是我的oracle用户的shell是bash啊 |
hpux 回复于:2003-06-11 11:35:18 |
你不是正好可以调试一下看看if [$curr_sh="sh"] 这句实际上是怎么执行的? |
uman 回复于:2003-06-11 12:15:38 |
好啊
等待续集 |
blackwolfdog 回复于:2003-06-11 17:14:39 |
找到原因了,请看
/home/oracle/lyc]more new.sh #!/bin/bash curr_sh=`ps|grep $$|awk '{print $4}'` set -x echo $curr_sh if [ $curr_sh="bash" ] then echo "The current shell is bash." else echo "The current shell isn't bash,it's $curr_sh." fi echo $curr_sh /home/oracle/lyc]./new.sh + echo new.sh new.sh + '[ ']' + echo 'The current shell is bash.' The current shell is bash. + echo new.sh new.sh /home/oracle/lyc] 这个是修改之前的脚本 经过修改后 /home/oracle/lyc]more new.sh #!/bin/bash curr_sh=`ps|grep $$|awk '{print $4}'` set -x echo $curr_sh if [ $curr_sh = "bash" ] then echo "The current shell is bash." else echo "The current shell isn't bash,it's $curr_sh." fi echo $curr_sh /home/oracle/lyc]./new.sh + echo new.sh new.sh + '[' new.sh = bash ']' + echo 'The current shell isn'\''t bash,it'\''s new.sh.' The current shell isn't bash,it's new.sh. + echo new.sh new.sh /home/oracle/lyc] 两个脚本有什么区别?自己看看 注意等于号=两边的空格,原来是这样的,唉!! |
wnoracle 回复于:2003-06-12 10:17:26 |
谢 |
coolhong 回复于:2003-06-19 15:41:24 |
很好,正在努力ing…… |
ylfind 回复于:2003-06-20 10:17:54 |
good good study
day day up! |
alian0511 回复于:2003-06-21 14:39:57 |
好 |
unix_wood 回复于:2003-06-23 11:55:13 |
新手就是需要得到高手的这样耐心指导!希望能有续级! |
wildboy 回复于:2003-06-24 11:47:05 |
顶 |
ffaatt 回复于:2003-06-30 13:03:02 |
好 |
jijianjun 回复于:2003-06-30 15:54:53 |
To hpux:
我不认识你,但是我要谢谢你 |
hpux 回复于:2003-06-30 20:46:39 |
[quote:11d07a76f7="jijianjun"]To hpux:
我不认识你,但是我要谢谢你[/quote:11d07a76f7] 好友不言谢!!! |
luixy 回复于:2003-07-24 10:50:41 |
我是初学者,看到这贴如获至宝
但我还不清楚以下这句代码等于号后面的符号怎样输入的 =`ps|grep $$ |
luixy 回复于:2003-07-24 10:54:25 |
我是初学者,读到这贴受益良多,但我还不明白以下这句代码等于号后面的"豆"号怎样输入
=`ps|grep $$ ops: |
沉寂 回复于:2003-07-24 11:23:59 |
[quote:9a2697da85="luixy"]我是初学者,读到这贴受益良多,但我还不明白以下这句代码等于号后面的"豆"号怎样输入
=`ps|grep $$ ops:[/quote:9a2697da85] 主键盘左上角的那个键 |
hudong 回复于:2003-07-26 20:11:30 |
[code:1:82d76644bf]
#./getsh.sh + [ getsh.sh = sh ] + echo The current shell isn’t sh. The current shell isn’t sh. 当前Shell已经不是sh而是脚本文件getsh.sh,难怪! [/code:1:82d76644bf] hpux大哥,我不是很明白,能不能给解释一下?谢谢! |
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/