无法轻易杀死由 bash 启动的子进程

无法轻易杀死由 bash 启动的子进程

一般来说,我发现子进程是一场噩梦 - 如果我有这个:

#!/usr/bin/env bash

( proc_one ) &
( proc_two ) &

wait

如果我 ctrl-C 这个脚本,它们仍然运行后台并中断我在终端中输入的任何内容。我最终只需要关闭终端即可。

是否有一种模式可用于通过终端轻松终止子进程?

答案1

有几个选项可以解决这个问题。

首先,您可以忽略它们发送到终端的输出。但如果这太具有破坏性,您可以使用以下命令告诉终端停止接受它stty tostop

其次,你可以扼杀这些工作。使用命令ps t找到它们,然后通过pid杀死。

如果窗口中的输出太多,您可以打开另一个窗口并从那里杀死它们。 (但是这样 plainps t就不行了,你必须给 t 选项指定另一个窗口的 tty 名称。)或者使用 tostop 来停止输出,然后杀死它们。

另一种方法是修改脚本来解决这个问题。当脚本启动每个进程时,它可以记录每个进程id$!并将其保存在变量中。然后脚本可以捕获 ctrl-c,当发生这种情况时,它可以在执行 ctrl-c 并退出之前自行终止这两个作业。

答案2

这是zzOne:

#! /bin/bash

Killer () {
    printf 1>&2 '\n.. Killing %s' "${Pids[@]}"
    kill -SIGKILL "${Pids[@]}"
}
trap 'Killer' SIGINT

./zzTwo 5 4 & Pids+=( "${!}" )  
./zzTwo 3 7 & Pids+=( "${!}" )

wait
printf 1>&2 '\n.. %s exits\n' "${$}"

这是 zzTwo (模拟您的 proc_xxx,具有不同的间隔):

#! /bin/bash

for (( j = 0; j < "${1}"; j++ )); do
    printf 1>&2 'Pid %d at %(%T)T\n' "${$}" -1
    sleep "${2}"
done

printf 1>&2 'Pid %d exits at %(%T)T\n' "${$}" -1

和测试:

$ ./zzOne
Pid 10951 at 22:35:28
Pid 10952 at 22:35:28
Pid 10951 at 22:35:32
Pid 10952 at 22:35:35
Pid 10951 at 22:35:36
^C
.. Killing 10951
.. Killing 10952
.. 10950 exits
$ 

有点冗长,但您可以使用sourceKiller 函数并陷入多个脚本中。

相关内容