在单个 ctrl+c 输入时杀死 bash 中的多个进程

Killing multiple processes in bash upon a single ctrl+c input

我的脚本执行三个进程 运行 循环执行直到它们被中断。我运行前两个在背景,最后一个在前景。

#!/bin/bash

./p1 &
PID1=$!

./p2 | tee p2.log & 
PID2=$!

sleep 1
./p3 "$(head -1 p2.log)" | tee p2.log

kill -KILL $PID1 $PID2

我想知道如何获得,一旦前台进程收到中断信号(Ctrl + C),其余进程将结束执行。

原则上,我只是简单地尝试在后台运行ning进程的PID上使用kill -KILL命令,但是当使用管道重定向它们的输出时,出现异常:

Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
./script.sh: line 15: kill: (9106) - The process does not exist
./script.sh: line 15: kill: (9104) - The process does not exist

示例循环过程(p1、p2、p3)如下:

#!/bin/bash

while true; do
    echo "Hello World"
    sleep 1
done

如何使用单个 CTRL-C (^C) 来终止多个进程?

我没有得到和你一样的错误,但你可以捕获 ctrl+c 输入,然后用它做一些事情,即终止前两个进程。我编辑了您的问题以包括示例循环过程(即我对 p1、p2 和 p3 使用了相同的代码)如果有明显不同,请评论或编辑此示例代码,或者我遗漏了导致您最初引用的某些组件错误。假设这些示例 p1、p2、p3 与您使用的相似,您的新中央脚本将是:

#!/bin/bash

trap ctrl_c INT

function ctrl_c() {
    echo "Trapped CTRL_C"
    kill -KILL $PID1 $PID2
}

./p1 &
PID1=$!
echo "PID1=" $PID1

./p2 | tee p2.log &
PID2=$!
echo "PID2=" $PID2
sleep 1

./p3 "$(head -1 p2.log)" | tee p2.log

我添加了 PID1 和 PID2 的回显,这样我就可以在另一个终端中检查进程是否真的被杀死了。为此

  • 运行 一个终端的中心脚本
  • 将回显 PID 值
  • 然后您可以在单独的终端中通过 ps [PID#] 检查它们是否存在。
  • 确认它们存在后,回到原来的终端,ctrl+c
  • 循环和管道应该停止
  • 返回第二个终端并再次ps [PID#]验证进程是否已终止

我从 here but there are a few ways to go about it. See another syntax here

中获取了这个解决方案