IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

bash下利用trap捕捉信号量

淘宝数据平台与产品部官方博客 tbdata.org 2011-03-06 22:51:43 累计浏览 4,926 次
本机暂存

我在之前的文章里写了myisam读数据压缩的情况,最近决定把它用在生产环境上,所以避免不了写一个“安全”的处理脚本放在DB服务器上,这就引入了本文所讨论的话题。

我希望这个bash脚本在退出的时候做一些事情,包括:

  1. 它启动的切到后台的job需要被杀死;

  2. 一些临时文件的清理。

在这个脚本里我用到了trap这个命令,关于它,你可以man一下,我这里就不嗦了。直接上示例代码:

$ cat test_trap.sh
 
declare -i run_terminate=0
 
trap "run_terminate=1" SIGINT SIGTERM
 
# 启动io监控,IO较大时不进行压缩
vmstat 1 >> ./a.log &
 
while [ ${run_terminate} -eq 0 ]
do
    # 核心代码
    sleep 30
done
 
for pid in $(ps -ef | awk -v p=${$} '{if ($3 == p){print $2}}')
do
    kill -9 ${pid} > /dev/null
done
 
rm -f ./a.log
echo "Terminated."

在上面的代码中,我们捕捉INT信号(CTRL+C)和TERM信号(kill产生)。运行程序:

$ /bin/bash test_trap.sh
 
^C

按照我们预期的,当我CTRL+C退出程序,或者kill进程时,上面的脚本应该停掉vmstat进程,并且删除a.log,输出“Terminated”后退出。

但是,CTRL+C确实按照我们的设想进行了。可kill之后程序并没有任何反应,这是为何?

Google了一遍,天下文章一大抄,相似的例子,却没有人抛出这个问题。思索了半天,幡然醒悟:

  1. kill(killall)命令只是发出一个TERM信号(15),至于这个信号是否被对应进程捕捉并处理了,它并不管;

  2. kill发出的时候,test_trap.sh正在sleep——这个时间有点长(30秒)。

也就是说,等它“睡醒”了,它自然会处理TERM信号的。不信,你多等一会。

同分类推荐文章

  1. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. Bash的模式和配置文件加载 (累计阅读 24,409)
  2. 阿里巴巴离职DBA 35岁总结的职业生涯 (累计阅读 19,625)
  3. 高效Linux用户需要了解的命令行技能 (累计阅读 12,825)
  4. linux 建立两台机器的信任关系 (累计阅读 11,484)
  5. 利用脚本分析日志并利用snmp自定义OID,再通过cacti画图 (累计阅读 10,071)
  6. linux中设置alias永久生效 (累计阅读 9,606)
  7. Bash脚本15分钟进阶教程 (累计阅读 9,060)
  8. 批量添加主机到 Cacti 的命令行工具 (累计阅读 8,558)
  9. 你可能不知道的Shell (累计阅读 8,313)
  10. Linux shell脚本使用while循环执行ssh的注意事项 (累计阅读 8,189)