关于trap ERR的一个bash shell set 参数之一:-E,

bash shell(rh linux平台,bash 3.2),以后基本上默认是这个平台,不再强调了呵。

 

今天有个写java的群友问了个shell问题(看看写java的人起的函数名,都这么java,呵呵)

为什么 rm文件不存在,没有调起trap

trap 'echo 抓住非零返回值' ERR

function preparePvmsDailyData { local PVMSDATADIR="/apps/pvmsnas/temp" rm "${PVMSDATADIR}"/*JRN* echo helloword }

 

trap以前虽然是用过的,但他这问题一时还回答不上来,然后就查起文档,现学现卖了起来

 

首先还是查man trap,看看啥情况会调起

       trap [-lp] [[arg] sigspec ...]
              The  command arg is to be read and executed when the shell receives signal(s) sigspec.

              If a sigspec is ERR, the command arg is executed
              whenever a simple command has a non-zero exit status, subject to the following conditions.  The ERR trap
              is not executed if the failed command is part of the command list immediately following a while or until
              keyword, part of the test in an if statement, part of a && or || list, or if the command's return  value
              is  being  inverted via !.

 

也就是说,排除排除在while,until,反的特殊使用情况,对于tra ERR下,命令一旦出错便会报错。

 

既然如此,为什么没有报错?是不是信号丢了?

简单写了个脚本:

trap 'echo 抓住非零返回值' ERR sub() { ls dfqwefi rm fwjepf } sub

 

然后执行,发现只报了一个trap

 

开始怀疑跟跟函数调用有没有关系?是不是没有报错

于是在ls命令与rm命令中sleep了一秒中。

 

发现结果还是一样,只报了一个trap?

是函数只接收一个信号,还是多个信号覆盖丢了?

 

继续翻info 文档,info 文档操作来不熟,慢慢的/trap+enter

结果先找到了一个set 参数-E

              -E      If set, any trap on ERR is inherited by shell functions,
                      command  substitutions,  and commands executed in a sub-
                      shell environment.  The ERR trap is normally not  inher-
                      ited in such cases.

原因在于:

这样就明白了,bash默认的关闭了 函数执行体的trap,即不跟进(英文单词叫: inherited )函数内部,

所以我上边的例子,之所以只报一个错,是因为脚本调用了一次sub函数,并返回(通过函数最后一个命令)了非零值。

 

 

回头看看java兄的程序,之所以rm不起效果,也是没理解好trap ERR的机制,解决方法可以有这几种:

1:去掉echo helloword
2:在rm下保存存$?,再echo helloword里把保存值return
     保存$?  :  re=$?
     return :   return $re
3:把trap 写进你的函数里:
4:在脚本最开始处加一个: set -E

 

其中3,4二种方法让trap跟进了函数。

 

 

另外set的一个参数 -e,则是出错即退出,可以做一个有趣的实验

在用户的 ~/.bash_profile里加入下边这二句:

 

trap '你命令出错了,我要退出了' ERR

set -e

 

一出错,即shell退出。

呵呵

开个小玩笑

事实上这些选项是可以用在程序调试上边的

比如set -u,一旦脚本中变量未定义,但报错退出

说到shell调试推荐一个网页:

 

shell调试技术: <http://hi.baidu.com/dabo12/blog/item/b0b799359e405a8da71e122e.html>

 

 

 

你可能感兴趣的:(java,shell,command,脚本,bash,文档)