一般来说,我发现子进程是一场噩梦 - 如果我有这个:
#!/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
$
有点冗长,但您可以使用source
Killer 函数并陷入多个脚本中。