加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

shell脚本调试

(2010-12-22 17:34:40)
标签:

脚本调试

shell

it

分类: 操作系统

                                         作者:韩涛

 

在日常的脚本编写或者维护脚本的时候经常会遇到需要调试的情况,用echo,用/bin/sh -x 打出来确实是常用两种办法,但这两种办法有些时候不够灵活,下面介绍一些常用的调试脚本的其它方法。
trap是个bulidin命令,可以指定脚本在捕获到该信号量时做出的行为,系统中可以调用kill -l查看系统所有的信号量,trap可以用来捕捉大部分这些信号并自定义脚本行为。
在shell脚本在执行时,会产生三个所谓的“伪信号”(之所以称为“伪信号”是因为这三个信号是由shell产生的,而其它的信号是由操作系统产生的),用trap捕获这三个伪信号并输出相关信息对调试非常有帮助。

shell的伪信号:
信号名      产生时间
EXIT        从一个函数中退出或整个脚本执行完毕
ERR         当一条命令返回非零状态时(代表命令执行不成功)
DEBUG       脚本中第一条命令执行之前

通过获取EXIT信号,我们可以在shell脚本终止执行或从函数中退出时,输出想要跟踪的变量值,并由此来判断脚本的执行状态以及出错原因。
使用方法是:

trap  'command' EXIT/ERR/DEBUG

通过捕获ERR信号,我们可以方便的跟踪执行不成功的命令或函数,并输出相关的调试信息,以下是一个捕获ERR信号的实例脚本,其中的$LINENO是一个shell内置变量,代表shell当前的行号。

 #!/bin/bash
    ERRTRAP(){
       echo "[LINE:$1] ERROR:Command or function exited with status $?"
    }
    foo(){
       return 1
    }
    trap 'ERRTRAP $LINENO' ERR
    abc
    10 foo

运行结果
./test: line 9: abc: command not found
[LINE:9] ERROR:Command or function exited with status 127
[LINE:10] ERROR:Command or function exited with status 1

通过伪信号DEBUG全程跟踪某变量


    #!/bin/bash
    trap 'echo "before execute line:$LINENO,a=$a,b=$b,c=$c"' DEBUG
    a=1
    [ "$a" -eq 1 ]  && b=2 || b=1
    c=3
    echo "end"
运行结果:
before execute line:3,a=,b=,c=
before execute line:4,a=1,b=,c=
before execute line:4,a=1,b=,c=
before execute line:5,a=1,b=2,c=
before execute line:6,a=1,b=2,c=3
end

tee命令
tee命令将标准输入中读取数据,将内容写到标准输出中同时将标准输入记录到文本中,这个命令通常用来辅助带管道的shell命令的追踪调试;
ifconfig|grep 'inet '|grep -v 127.0.0.1|tee res1.txt|cut -d" " -f 4
less res1.txt
 inet 10.10.99.3 netmask 0xffffff00 broadcast 10.10.99.255
 inet 10.10.99.4 netmask 0xffffff00 broadcast 10.10.99.255

使用“调试钩子”
用DEBUG将调试钩子打开,后期程序发布的时候可以通过export DEBUG将DEBUG置为0关闭DEBUG而不用一一的去删除调试程序
实际中可以用DEBUG写个函数,通过调用来确定调用钩子。

#!/bin/bash
    debug(){
     [ $DEBUG -eq 1 ] && $@
    }
    a=1
    debug echo "a=$a"
    [ "$a" -eq 1 ] && b=2 || b=1
    debug echo "b=$b"
    c=3
    10 debug echo "c=$c"

./test
export DEBUG=1
./test
a=1
b=2
c=3


附送一个最近写的东西,觉得比较实用,主要用处是在没有控制界面的存储式服务器看raid组中磁盘状态的小脚本,包括rebuild和copyback的进程,需要是LSi的芯片和安装Megacli


#!/bin/bash
MegaCli="/usr/sbin/MegaCli"
[ "$UID" -ne "0" ] && {
 echo "Permission denied,You Must be Root";exit 1
}
[ -e "$MegaCli" -a -x "$MegaCli"  ] || {
 echo "/usr/sbin/MegaCli  Can't Accessed";exit 1
}
function getlist(){
echo -ne "\033[40;32;25m"
echo
$MegaCli -PDList -aALL  |sed '/^$/d'|awk -F":" '$1~/Slot/{printf("%s:%4s ",$1,$2)};$1~/Media Error Count/{if($2!=0){printf("\033[40;31;5m%s %4s\033[40;32;25m ",$1,$2)}else{printf("%s %4s ",$1,$2)}};$1~/Other Error Count/{if($2!=0){printf("\033[40;35;25m%s %s\033[40;32;25m ",$1,$2)}else{printf("%s %s ",$1,$2)}};$1~/Firmware state/{if($2 != " Online" && $2 != " Hotspare" && $2 != " Unconfigured(good)"){printf("\033[40;31;5m%s %s\033[40;32;25m\n",$1,"<"$2" >")}else{printf("%s %s\n",$1,"<"$2" >")}}'
echo
echo -ne "\033[0m"
}
function showrebuildprocess(){
Slotnum=`getlist|grep Rebuild|awk '{print $3}'`
[ "$Slotnum" != "" ] && {
echo -ne "\033[40;31;25m"
$MegaCli -PDRbld -ShowProg -PhysDrv [1:$Slotnum] -a0
echo
}
echo -ne "\033[0m"
}
getlist
showrebuildprocess

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有