shell trap命令的一些特殊注意的地方
2017-02-08 11:35
609 查看
实验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"
ctrl+c后能立即停止signal.bash脚本的运行。
分析: 前台运行signal.bash脚本,其所有子程序(外部命令)和signal.bash程序在同一个进程组。而ctrl+c会发送给前台进程组所有进程INT信号。signal.bash运行后会产生两个进程,一个是signal.bash程序本身,另外一个是sleep程序(sleep是外部命令)。而sleep和signal.bash在同一个前台进程组,所以ctrl+c时,sleep程序由于处于
实验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信号。
有下面的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信号。
相关文章推荐
- 关于水晶报表打包的一些注意的地方!
- javascript的一些应该注意的地方,一边学一边更新
- load data infile 需要注意的一些地方
- shell脚本中一些特殊符号
- 我们来看看load data infile 需要注意的一些地方
- 关于水晶报表打包的一些注意的地方!
- SQL开发中容易忽视的一些小地方(一)【null的用法及注意事项】
- JSP学习过程中的一些注意的地方
- shell脚本(从一些文件中查找含有特定字符的文件,将转移到指定地方)
- 整理出一些运用ASP+ACCESS过程的技巧或需注意的地方。
- lucene 2.0中的一些要注意的地方
- C/C++中一些要注意的地方
- 编写代码时应该注意的一些地方
- 我们来看看load data infile 需要注意的一些地方
- 个人总结的一些应该注意和学习的一些地方
- 使用资源文件要注意的一些地方
- 学到一些shell命令
- Shell中的特殊字符(Shell命令)
- 我们来看看load data infile 需要注意的一些地方
- shell中的一些特殊变量 [转]