我有一个调用kill 0的脚本。我想从另一个脚本调用该脚本,并让外部脚本继续执行。(kill 0向调用进程的进程组中的每个进程发送默认为SIGTERM的信号;请参阅man 2 kill
kill0.sh

#!/bin/sh

kill 0

caller.sh
#!/bin/sh

echo BEFORE
./kill0.sh
echo AFTER

当前的行为是:
$ ./caller.sh
BEFORE
Terminated
$

如何修改caller.sh以便在调用AFTER后打印kill0.sh
修改kill0.sh不是一个选项。假设kill0.sh可能在调用kill 0之前从stdin读取并写入stdout和/或stderr,我不想干扰它。我仍然希望kill 0命令杀死kill0.sh进程本身;我只是不希望它也杀死调用方。
我使用的是ubuntu 16.10x86_64,/bin/sh是指向dash的符号链接。这不重要,我更喜欢不依赖于这个的答案。
当然,这是一个更大脚本集的简化版本,所以我有可能遇到xy问题,但我认为这里所述的问题解决方案应该让我解决实际问题。(我有一个包装器脚本,它调用一个指定的命令,捕获并显示它的输出,以及一些其他的铃声和口哨声。)

最佳答案

一种解决方案
您需要在父级中捕获信号,但在子级中启用它。所以像run-kill0.sh这样的脚本可以是:

#!/bin/sh

echo BEFORE
trap '' TERM
(trap 15; exec ./kill0.sh)
echo AFTER

第一个trap禁用术语信号。在运行trap脚本之前,子shell中的第二个kill0.sh重新启用信号(使用信号号而不是名称-见下文)。使用exec是一个小优化-您可以省略它,它也会起到同样的作用。
模糊句法细节的离题
为什么在子壳中15而不是TERM?因为当我用TERM而不是15测试时,我得到:
$ sh -x run-kill0.sh
+ echo BEFORE
BEFORE
+ trap '' TERM
+ trap TERM
trap: usage: trap [-lp] [arg signal_spec ...]
+ echo AFTER
AFTER
$

当我用15代替TERM(两次)时,我得到:
$ sh -x run-kill0.sh
+ echo BEFORE
BEFORE
+ trap '' 15
+ trap 15
+ exec ./kill0.sh
Terminated: 15
+ echo AFTER
AFTER
$

使用TERM代替第一个15也可以工作。
关于trap的bash文档
研究trap的bash手册显示:
trap [-lp] [arg] [sigspec …]
当shell接收到sigspec信号时,将读取并执行arg中的命令。如果arg不存在(并且有一个sigspec)或等于“-”,则每个指定信号的配置都将重置为启动shell时的值。
第二种解决方案
第二句话是关键:trap - TERM应该(而且从经验上讲确实)起作用。
#!/bin/sh

echo BEFORE
trap '' TERM
(trap - TERM; exec ./kill0.sh)
echo AFTER

运行结果:
$ sh -x run-kill0.sh
+ echo BEFORE
BEFORE
+ trap '' TERM
+ trap - TERM
+ exec ./kill0.sh
Terminated: 15
+ echo AFTER
AFTER
$

我刚刚想起来为什么我用数字而不是名字(但我的借口是,在那些日子里它不是bash,当我学会它的时候它不认识信号名称)。
trap的posix文档
然而,在bash的辩护中,trap的posix规范指出:
如果第一个操作数是无符号十进制整数,shell应将所有操作数视为条件,并将每个条件重置为默认值。否则,如果存在操作数,则第一个操作数被视为操作,其余操作数被视为条件。
如果action为“-”,shell应将每个条件重置为默认值。如果action为空(“”),则shell将忽略出现的每个指定条件。
这比bash文档更清楚,imo。它说明了trap 15工作的原因。演示文稿中还有一个小故障。概要说(在一行上):
trap n [condition...]trap [action condition...]

它应该说(两行):
trapn[condition...]trap [
action condition...]

关于linux - 在“杀死0”后恢复,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44710421/

10-12 01:03