shell脚本调试

在日常的脚本编写或者维护脚本的时候经常会遇到需要调试的情况,用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
     2 ERRTRAP(){
     3    echo "[LINE:$1] ERROR:Command or function exited with status $?"
     4 }
     5 foo(){
     6    return 1
     7 }
     8 trap 'ERRTRAP $LINENO' ERR
     9 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全程跟踪某变量


     1 #!/bin/bash
     2 trap 'echo "before execute line:$LINENO,a=$a,b=$b,c=$c"' DEBUG
     3 a=1
     4 [ "$a" -eq 1 ]  && b=2 || b=1
     5 c=3
     6 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
     2 debug(){
     3  [ $DEBUG -eq 1 ] && $@
     4 }
     5 a=1
     6 debug echo "a=$a"
     7 [ "$a" -eq 1 ] && b=2 || b=1
     8 debug echo "b=$b"
     9 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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值