并行运行命令,但如果父进程被杀死,则同时杀死两个命令?

并行运行命令,但如果父进程被杀死,则同时杀死两个命令?

有没有什么方法可以在 Bash 中并行运行两个命令,这样,如果 shell 被强制杀死,那么这两个命令也能保证被杀死?

简单的方法&行不通,因为如果我这样做

sh -c 'sleep 6 & sleep 3'

那么即使被杀,第一个sleep也会继续徘徊。sh

答案1

@lesmana 的解决方案,使用 trap 是传统方法,但如前所述,无法处理这种kill -9情况。

还有一种替代方法,设置一个进程来监视主进程,并在主进程退出时发出终止命令。进行监控的一个简单方法是建立一个到监视器的管道,当主进程退出时,内核将关闭监视器可以检测到的管道。

这是一个例子

#!/bin/bash
# show monitoring main process - Icarus Sparry
# [email protected]

# Handler function. Reads from stdin. If it doesn't read the word clean
# then send SIGINT to the process group.
handler(){
    read
    [ "$REPLY" = "clean" ] || kill -INT -$$
}

# invoke handler as a coprocess. 
coproc handler

# some work in the background, wait for 20 seconds and print a message
{ sleep 20 ; echo bye 20 ; } &

# some work in the foreground
sleep 5 ; echo bye 5

# At this point tell the coprocess it was a clean end, so don't
# terminate the background
echo clean >&"${COPROC[1]}"

运行此命令将在 5 秒后输出,bye 515 秒后输出bye 20。终止进程将导致协进程终止后台睡眠。

如果希望在前台工作完成时终止后台处理,则省略 Final echo clean >&"${COPROC[1]}",并可以选择从处理程序中删除[ "$REPLY" = "clean" ] ||,留下 read 和kill。

答案2

trap 'kill 0' EXIT在主脚本中使用。这将在脚本退出时杀死所有孩子。不管脚本如何退出。除了kill -9。稍后会详细介绍。

为了演示我创建了两个文件

$ cat killchildren 
#! /bin/sh
trap 'echo killing all children; kill 0' EXIT # this is the important line
./sleepx 4 &
./sleepx 2
echo killchildren done

$ cat sleepx 
#! /bin/sh
trap 'echo sleep$1 killed' EXIT # just print that it was killed
sleep $1
trap - EXIT # clear trap so not print that it was killed
echo sleep$1 done

在这里它只是运行并保持不变

$ ./killchildren 
sleep2 done
killchildren done
killing all children
sleep4 killed

在这里它被正常杀死kill(注意我提高了睡眠时间,因为我打字速度不快)

$ ./killchildren &
[1] 13248

$ kill 13248
killing all children
sleep8 killed
sleep10 killed
[1]+  Terminated              ./killchildren

在这里它被杀死了kill -9

$ ./killchildren &
[1] 13259

$ kill -9 13259
[1]+  Killed                  ./killchildren

$ # ... time passes ...
sleep8 done
sleep10 done

请注意,主脚本没有退出消息,孩子们也没有被杀死。

没有经过太多测试。截至 2018 年,至少可以在 arch linux 上与 sh 配合使用。


如果主脚本是 ,它将不起作用kill -9。因为 的语义kill -9是立即终止而不让进程执行任何操作。甚至没有陷阱处理。

也就是说,无论什么杀死你的进程都不应该用kill -9.我认为这是一个错误。以下是有关为什么不这样做的更多信息kill -9

相关内容