Linux的trap命令问题

在项目中碰到个问题,某个php脚本文件在周期时间内被重复执行了,各种排查始终找不到原因,后来发现原来是trap的坑引起的。

在我们的项目中,有个shell脚本用于定时执行各种php文件,内容很简单,文件执行时生成lock文件,如果lock文件存在输出一段错误信息,不存在则引入执行php文件并生成lock,其中一段是这样:
用于删除lock文件

trap "rm -f ${tmpfile}" 0 1 2 3 9 15

而我们在存在lock时输出提示信息,继续向下执行,shell文件正常执行完毕,此时就会被信号‘0’被捕获

 if [ -e $tmpfile ];then
   echo "is running"
 else
   ....
 fi

就造成了删除lock重复执行php文件的问题,这时就需要在输出错误信息的判断中加上:

 if [ -e $tmpfile ];then
   echo "is running"
   trap '' 0
 else
   ....
 fi

忽略‘0’这个信号,也就是不触发rm。问题得到解决

说到这里就不得不提trap的三个伪信号:
shell脚本在执行时,会产生三个所谓的“伪信号“,之所以称之为“伪信号”是因为这三个信号是由shell产生的,而其它的信号是由操作系统产生的

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

‘EXIT’信号在数字标识上为0,也就是:
(其他两种没测试,需要再测一下是不是也能用0标识)

trap 'commands' 0

其他几种常用的信号:

信号名何时产生
SIGHUP(1)本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。
SIGINT(2)程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
SIGQUIT(3)和SIGINT类似, 但由QUIT字符(通常是Ctrl-)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。
SIGKILL(9)用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。
SIGTERM(15)程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。

注:单引号和双引号是不同的,当shell程序第一次碰到trap语句时,将把commands中的命令扫描一遍。此时若commands是用单引号括起来的话,那么shell不会对commands中的变量和命令进行替换, 否则commands中的变量和命令将用当时具体的值来替换。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值