Bash 在一个ctrl+;c输入

Bash 在一个ctrl+;c输入,bash,shell,bash-trap,Bash,Shell,Bash Trap,我的脚本执行三个循环运行的进程,直到它们被中断。我在后台运行前两个,在前台运行最后一个 #!/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),其余进程就结束执行 原则上,我只是尝试在后台运行的进程的PID

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

#!/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
),其余进程就结束执行

原则上,我只是尝试在后台运行的进程的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

如何使用单个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#]
    以验证进程是否已终止

我从中获得了这个解决方案,但有几种方法。请参见另一种语法

我没有收到与您相同的错误,但您可以捕获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#]
    以验证进程是否已终止

我从中获得了这个解决方案,但有几种方法。请参阅另一个语法

注意,当您将管道作为背景时,如
/p2 | teep2.log&
,由
$报告的pid
是管道的最后一个命令的代码。因此,如果终止pid,则可能终止
tee
,而不是
p2
。您可以使用命名管道、协进程或进程替换来解决这个问题
/p2>>(teep2.log)和
请注意,当您将管道作为背景时,如
/p2 | teep2.log和
,由
$报告的pid
是管道的最后一个命令的代码。因此,如果终止pid,则可能终止
tee
,而不是
p2
。您可以使用命名管道、协进程或进程替换来解决这个问题<代码>/p2>>(tee p2.log)和