• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

HP-UX环境下Shell程序调试实验教程

发布: 2007-6-08 22:43 | 作者: seanhe | 来源: | 查看: 21次 | 进入软件测试论坛讨论

领测软件测试网
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/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网