shell trap命令的一些特殊注意的地方

实验1

有下面的bash代码,脚本名signal.bash。

#!/bin/bash
trap 'echo INTRRUPTED BY SIGNAL INT' INT
seconds0=$(date +%s)
sleep 60s
seconds1=$(date +%s)
echo "sleeped seconds : $((seconds1 - seconds0))s"

chenglin@ubuntu-chenglin:~/shellscript/other$ time ./signal.bash 
^CINTRRUPTED BY SIGNAL INT
sleeped seconds : 22s

real	0m21.427s
user	0m0.000s
sys	0m0.004s

ctrl+c后能立即停止signal.bash脚本的运行。


分析: 前台运行signal.bash脚本,其所有子程序(外部命令)和signal.bash程序在同一个进程组。而ctrl+c会发送给前台进程组所有进程INT信号。signal.bash运行后会产生两个进程,一个是signal.bash程序本身,另外一个是sleep程序(sleep是外部命令)。而sleep和signal.bash在同一个前台进程组,所以ctrl+c时,sleep程序由于处于TASK_INTERRUPTIBLE状态(ps -axu可以看到其状态是S+)。所以会被信号INT唤醒,信号action为终止进程,自然父进程继续运行。得出运行,直到sleep被信号INT中断的睡眠时间。


实验2

现在做另外一个实验:

开两个终端,第一个终端里面运行time ./signal.bash。迅速(60s内)在第二个终端里面运行如下:

chenglin@ubuntu-chenglin:~/shellscript/powerConsumption-net$ pgrep -f signal.bash -l
25700 signal.bash
chenglin@ubuntu-chenglin:~/shellscript/powerConsumption-net$ kill -INT 25700

发现第一个终端中打印如下:

chenglin@ubuntu-chenglin:~/shellscript/other$ time ./signal.bash 
INTRRUPTED BY SIGNAL INT
sleeped seconds : 60s

real	1m0.013s
user	0m0.004s
sys	0m0.004s

第二个终端不能立即停止第一个终端中signal.bash的运行。

分析: 在第二个终端是,信号INT是指定发送给signal.bash的,而不是sleep的,所以sleep没有接收到INT信号,而继续睡眠,直到指定的时间60s后,当60s后,sleep返回。主程序signal.bash此时才会处理信号。打印INTRRUPTED BY SIGNAL INT,说明处理了信号INT。


实验3

现在做第三个实验:

开两个终端,第一个终端里面运行time ./signal.bash。迅速(60s内)在第二个终端里面运行如下:

chenglin@ubuntu-chenglin:~/shellscript/powerConsumption-net$ pgrep -f sleep -l
25708 sleep
chenglin@ubuntu-chenglin:~/shellscript/powerConsumption-net$ kill -INT 25708
chenglin@ubuntu-chenglin:~/shellscript/powerConsumption-net$ 
发现第一个终端打印如下:

chenglin@ubuntu-chenglin:~/shellscript/other$ time ./signal.bash 
sleeped seconds : 16s

real	0m15.915s
user	0m0.000s
sys	0m0.008s

分析:和实验2不同,这里是直接对sleep发送INT信号,可以直接唤醒sleep进程,并终止。但是注意到signal.bash并没有打印INTRRUPTED BY SIGNAL INT,因为信号是发给sleep进程,而不是signal.bash进程的。所以sgnal.bash进程无需处理INT信号。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值