gpt4 book ai didi

linux - 在 "kill 0"之后恢复

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:14 25 4
gpt4 key购买 nike

我有一个调用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 以便它在调用 kill0.sh 后打印 AFTER

修改 kill0.sh 不是一个选项。假设 kill0.sh 可能会在调用 kill 0 之前从 stdin 读取并写入 stdout 和/或 stderr,我不想干涉它。我仍然希望 kill 0 命令杀死 kill0.sh 进程本身;我只是不希望它也杀死调用者。

我使用的是 Ubuntu 16.10 x86_64,/bin/sh 是指向 dash 的符号链接(symbolic link)。这应该无关紧要,我更喜欢不依赖于此的答案。

这当然是一组更大脚本的简化版本,所以我有一定的 XY 问题风险,但我认为此处所述的问题解决方案应该可以让我解决实际问题。 (我有一个包装器脚本,它调用一个指定的命令,捕获并显示它的输出,还有一些其他的花哨的东西。)

最佳答案

一个解决方案

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

#!/bin/sh

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

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

关于模糊句法细节的题外话

为什么 15而不是 TERM在子 shell 中?因为当我用 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 …]

The commands in arg are to be read and executed when the shell receives signal sigspec. If arg is absent (and there is a single sigspec) or equal to ‘-’, each specified signal’s disposition is reset to the value it had when the shell was started.

第二种解决方案

第二句是关键: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 规范说:

If the first operand is an unsigned decimal integer, the shell shall treat all operands as conditions, and shall reset each condition to the default value. Otherwise, if there are operands, the first is treated as an action and the remaining as conditions.

If action is '-', the shell shall reset each condition to the default value. If action is null ( "" ), the shell shall ignore each specified condition if it arises.

这比 Bash 文档更清晰,IMO。它说明了为什么 trap 15作品。演示文稿中还有一个小故障。大纲说(在一行中):

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

它应该说(两行):

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

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com