我正在寻找一种方法来清理混乱时,我的顶级脚本退出。
特别是如果我想使用set -e,我希望后台进程在脚本退出时结束。
我正在寻找一种方法来清理混乱时,我的顶级脚本退出。
特别是如果我想使用set -e,我希望后台进程在脚本退出时结束。
当前回答
function cleanup_func {
sleep 0.5
echo cleanup
}
trap "exit \$exit_code" INT TERM
trap "exit_code=\$?; cleanup_func; kill 0" EXIT
# exit 1
# exit 0
类似于https://stackoverflow.com/a/22644006/10082476,但增加了退出代码
其他回答
更新:https://stackoverflow.com/a/53714583/302079通过添加退出状态和清除功能改进了这一点。
trap "exit" INT TERM
trap "kill 0" EXIT
为什么转换INT和TERM退出?因为两者都应该在不进入无限循环的情况下触发kill 0。
为什么在EXIT时触发kill 0 ?因为正常的脚本退出也应该触发kill 0。
为什么要杀死0?因为嵌套的子shell也需要被杀死。这会把整个过程树都画下来。
一个可以在Linux、BSD和MacOS x下工作的不错的版本。首先尝试发送SIGTERM,如果不成功,10秒后终止进程。
KillJobs() {
for job in $(jobs -p); do
kill -s SIGTERM $job > /dev/null 2>&1 || (sleep 10 && kill -9 $job > /dev/null 2>&1 &)
done
}
TrapQuit() {
# Whatever you need to clean here
KillJobs
}
trap TrapQuit EXIT
请注意,作业不包括子代进程。
脚本的加载。运行一个killall(或操作系统上可用的任何命令)命令,该命令在脚本完成后立即执行。
为了清理一些混乱,陷阱可以使用。它可以提供特定信号到达时执行的内容列表:
trap "echo hello" SIGINT
但如果shell退出,也可以用来执行一些东西:
trap "killall background" EXIT
它是内置的,所以帮助陷阱会给你信息(适用于bash)。如果你只想消灭后台工作,你可以做到
trap 'kill $(jobs -p)' EXIT
注意使用单个',以防止shell立即替换$()。
另一种选择是让脚本将自己设置为进程组的领导者,并在退出时在进程组上捕获killpg。