bash 陷阱在 shell 脚本中不起作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26858344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
trap not working in shell script?
提问by jph
I'm in the process of writing a script on OS X that needs to trap SIGTERM in order to kill some child processes before exiting. For the sake of this question I've boiled it down to the following minimal example that, for some reason, isn't working as I'd expect it to:
我正在 OS X 上编写脚本,该脚本需要捕获 SIGTERM 以便在退出之前杀死一些子进程。为了这个问题,我将其归结为以下最小示例,由于某种原因,它没有像我期望的那样工作:
#!/bin/sh
function shutdown()
{
touch foo.txt
exit 0
}
trap shutdown TERM
su -l myusername -c "sleep 9999"
I run this script in one terminal window, then switch to another and "ps -aef" yields this:
我在一个终端窗口中运行此脚本,然后切换到另一个窗口,“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
From that second window I then issue "kill -15 857", but the trap is never triggered. The script remains blocked on the "su" command.
然后我从第二个窗口发出“kill -15 857”,但从未触发陷阱。该脚本在“su”命令上仍然被阻止。
Any idea why? I get the feeling it's something simple.
知道为什么吗?我觉得这很简单。
回答by Edouard Thiel
The bash manual statesthat:
在bash的手册指出的是:
If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
如果 bash 正在等待命令完成并接收到设置了陷阱的信号,则在命令完成之前不会执行陷阱。
As gniourf_gniourfsays, this is a POSIX spec relative to signals in shells.
正如gniourf_gniourf所说,这是与 shells 中的信号相关的 POSIX 规范。
You can check it by trapping for instance SIGUSR1 in place of SIGTERM; you'll see that kill -TERM
will kill again the process.
您可以通过捕获例如 SIGUSR1 代替 SIGTERM 来检查它;你会看到这kill -TERM
将再次终止进程。
A solution is to run the command in background, then wait
for its termination. In this case the trap
will work. Try this:
一种解决方案是在后台运行该命令,然后wait
终止该命令。在这种情况下,trap
将起作用。尝试这个:
#! /bin/bash
shutdown()
{
touch foo.txt
exit 0
}
trap shutdown TERM
su -l myusername -c "sleep 9999" & # On Ubuntu: sudo su
wait
You will get two problems: su
won't be able to ask password in foreground; you will have to manually kill su
.
你会遇到两个问题:su
前台无法询问密码;你将不得不手动杀死su
。