我正在寻找一种方法来清理混乱时,我的顶级脚本退出。
特别是如果我想使用set -e,我希望后台进程在脚本退出时结束。
我正在寻找一种方法来清理混乱时,我的顶级脚本退出。
特别是如果我想使用set -e,我希望后台进程在脚本退出时结束。
当前回答
为了安全起见,我发现最好定义一个清理函数并从trap中调用它:
cleanup() {
local pids=$(jobs -pr)
[ -n "$pids" ] && kill $pids
}
trap "cleanup" INT QUIT TERM EXIT [...]
或完全避免该函数:
trap '[ -n "$(jobs -pr)" ] && kill $(jobs -pr)' INT QUIT TERM EXIT [...]
为什么?因为通过简单地使用陷阱'kill $(jobs -pr)'[…]当陷阱条件发出信号时,就会有后台作业在运行。当没有工作时,会看到以下(或类似的)消息:
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
因为jobs -pr是空的——我在那个“陷阱”中结束了(双关语)。
其他回答
为了安全起见,我发现最好定义一个清理函数并从trap中调用它:
cleanup() {
local pids=$(jobs -pr)
[ -n "$pids" ] && kill $pids
}
trap "cleanup" INT QUIT TERM EXIT [...]
或完全避免该函数:
trap '[ -n "$(jobs -pr)" ] && kill $(jobs -pr)' INT QUIT TERM EXIT [...]
为什么?因为通过简单地使用陷阱'kill $(jobs -pr)'[…]当陷阱条件发出信号时,就会有后台作业在运行。当没有工作时,会看到以下(或类似的)消息:
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
因为jobs -pr是空的——我在那个“陷阱”中结束了(双关语)。
脚本的加载。运行一个killall(或操作系统上可用的任何命令)命令,该命令在脚本完成后立即执行。
如果在子shell中调用Jobs -p,则不能在所有shell中工作,除非它的输出被重定向到文件而不是管道中。(我想它最初只是用于交互使用的。)
下面这些怎么样:
trap 'while kill %% 2>/dev/null; do jobs > /dev/null; done' INT TERM EXIT [...]
Debian的dash shell需要调用“jobs”,如果缺少当前作业(“%%”),则该shell无法更新。
通用解决方案,也在sh中工作(工作不输出任何东西到stdout):
trap "pkill -P $$" EXIT INT
为了清理一些混乱,陷阱可以使用。它可以提供特定信号到达时执行的内容列表:
trap "echo hello" SIGINT
但如果shell退出,也可以用来执行一些东西:
trap "killall background" EXIT
它是内置的,所以帮助陷阱会给你信息(适用于bash)。如果你只想消灭后台工作,你可以做到
trap 'kill $(jobs -p)' EXIT
注意使用单个',以防止shell立即替换$()。