在"杀死0"之后恢复

时间:2017-06-22 22:41:37

标签: linux shell sh kill-process

我有一个调用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.10 x86_64,而/bin/shdash的符号链接。这不重要,我更喜欢那些不依赖于此的答案。

这当然是更大的脚本集的简化版本,所以我有一定的XY问题风险,但我认为这里所说的问题的解决方案应该让我解决实际问题问题。 (我有一个包装器脚本,它调用指定的命令,捕获并显示其输出,以及其他一些铃声和口哨声。)

1 个答案:

答案 0 :(得分:1)

一种解决方案

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

#!/bin/sh

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

第一个trap禁用TERM信号。在运行trap脚本之前,子shell中的第二个kill0.sh重新启用信号(使用信号编号而不是名称 - 见下文)。使用exec是一个小优化 - 您可以省略它并且它将起作用。

关于晦涩的句法细节的讨论

为什么15而不是子shell中的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
$

我刚刚记得为什么我使用数字而不是名字(但我的理由是shell - 当时不是Bash - 当我学习它时不识别信号名称。)

trap

的POSIX文档

然而,在Bash的辩护中,trap的POSIX规范说:

  

如果第一个操作数是无符号十进制整数,则shell应将所有操作数视为条件,并将每个条件重置为默认值。否则,如果有操作数,则第一个被视为一个动作,其余被视为条件。

     

如果action为' - ',shell应将每个条件重置为默认值。如果action为null(“”),则shell应忽略每个指定的条件。

这比Bash文档IMO更清楚。它说明了为什么trap 15有效。演示文稿中也有一个小故障。概要说(在一条线上):

trap n [condition...]trap [action condition...]

应该说(两行):

trap n [ condition ...]
trap [ action condition ...]