防止 shell 分叉比其发起者存活的时间更长?

防止 shell 分叉比其发起者存活的时间更长?

如果我有一个类似这样的 Bash 脚本:

function repeat {
    while :; do
        echo repeating; sleep 1
    done
}
repeat &
echo running once

running once被打印一次,但repeat叉子永远存在,无限打印。

我应该如何防止repeat创建它的脚本退出后继续运行?

我想也许显式实例化一个新的bash -c解释器会迫使它退出,因为它的父进程已经消失了,但我猜孤儿进程被initPID 1 所采用。

使用另一个文件对此进行测试:

# repeat.bash
while :; do echo repeating; sleep 1; done

# fork.bash
bash -c "./repeat.bash & echo an exiting command"

运行./fork.bash仍然会导致repeat.bash永远继续在后台运行。

简单而懒惰的解决方案是将行添加到fork.bash

pkill repeat.bash

但是你最好不要再有另一个重要的进程使用这个名字,否则它也会被抹掉。

  1. 我想知道,是否有更好或可接受的方法来处理分叉 shell 中的后台作业,当创建它们的脚本(或进程)退出时,这些作业应该退出?

  2. 如果没有比盲目地使用pkilling相同名称的所有进程更好的方法,那么应该如何处理与网络服务器之类的东西一起运行的重复作业以退出?我想避免cron工作,因为脚本位于git存储库中,并且代码应该是独立的,无需更改/etc/.

答案1

这会在脚本退出之前终止后台进程:

trap '[ "$pid" ] && kill "$pid"' EXIT

function repeat {
    while :; do
        echo repeating; sleep 1
    done
}
repeat &
pid=$!
echo running once

怎么运行的

  • trap '[ "$pid" ] && kill "$pid"' EXIT

    这创建了一个陷阱。每当脚本即将退出时,就会运行单引号中的命令。该命令检查 shell 变量是否pid已分配非空值。如果有,则与之关联的进程将pid被终止。

  • pid=$!

    这会将前面的后台命令 () 的进程 ID 保存repeat &在 shell 变量中pid

改进

作为帕特里克在评论中指出,该脚本有可能被杀死后台进程启动但是变量pid已设置。我们可以用下面的代码来处理这种情况:

my_exit() {
    [ "$racing" ] && pid=$!
    [ "$pid" ] && kill "$pid"
}
trap my_exit EXIT

function repeat {
    while :; do
        echo repeating; sleep 1
    done
}

racing=Y
repeat &
pid=$!
racing=

echo running once

答案2

shelltcsh有一个hup命令告诉 shell 在退出时终止该命令:

hup mycommand...

这对运行函数没有帮助,因为tcsh它不支持函数。

在 中zsh,当启用作业控制时,默认情况下会对所有后台作业执行此操作。

$ zsh -c 'set -m; sleep 2 &'; ps
[1] 23672
zsh:1: warning: 1 jobs SIGHUPed

不过,在脚本中启用作业控制可能会产生副作用。

bash也可以做到这一点,但只有在交互时(尽管在脚本上使用 -i 调用它也可以做到这一点)并且只有在登录 shell 时(!?)。并且您需要启用该huponexit选项。所以:

 bash -O huponexit -lic 'sleep 2 &'

但这有很多副作用,所以可能不是一个好主意。

另一种选择zsh是在退出时杀死所有已知的正在运行的子进程(在任何情况下,我们都无法轻易了解孙子进程(我们也不总是想杀死它们))。zsh使其在$jobstates关联数组中可用:

TRAPEXIT() kill -s HUP ${${jobstates[(R)running:*]/#*:/}/%=*/}
trap exit INT HUP TERM

其他 shell 不会公开其子进程列表,但您可以终止 ppid 为 的进程$$,例如:

trap 'pkill -HUP -P "$$"' EXIT INT HUP TERM

相关内容