我正在编写OS X上的脚本,需要捕获SIGTERM以便在退出之前杀死一些子进程。为了这个问题,我把它归结为以下最小的例子,由于某种原因,它没有像我期望的那样工作:
#!/bin/sh
function shutdown()
{
touch foo.txt
exit 0
}
trap shutdown TERM
su -l myusername -c "sleep 9999"
我在一个终端窗口中运行此脚本,然后切换到另一个,“ps -aef”产生这个:
502 857 645 0 11:38PM ttys001 0:00.00 /bin/sh ./foo.sh
0 858 857 0 11:38PM ttys001 0:00.02 su -l myusername -c sleep 9999
502 859 858 0 11:38PM ttys001 0:00.00 sleep 9999
从第二个窗口开始,我发出“kill -15 857”,但永远不会触发陷阱。脚本在“su”命令上仍然被阻止。
知道为什么吗?我觉得这很简单。
答案 0 :(得分:13)
如果bash正在等待命令完成并收到信号 已经设置了陷阱,陷阱将不会执行,直到 命令完成。
正如gniourf_gniourf所说,这是相对于signals in shells的POSIX规范。
您可以通过捕获例如SIGUSR1代替SIGTERM来检查它;你会看到kill -TERM
会再次杀死这个过程。
解决方案是在后台运行命令,然后wait
终止它。在这种情况下,trap
将起作用。试试这个:
#! /bin/bash
shutdown()
{
touch foo.txt
exit 0
}
trap shutdown TERM
su -l myusername -c "sleep 9999" & # On Ubuntu: sudo su
wait
您将遇到两个问题:su
无法在前台询问密码;你必须手动杀死su
。