bash脚本如何能做到按Ctrl-C的一个后台任务等同? [英] How can bash script do the equivalent of Ctrl-C to a background task?
问题描述
有没有什么办法来调用一个子进程,使它和它的所有后代都发出了中断,就像如果你按Ctrl-C前台任务?我试图杀死调用长时间运行的孩子一个启动程序脚本。我试过杀-SIGINT $子
(不中断发送到其后代所以无操作)和杀-SIGINT - $子
(运行时交互而不是调用时它的工作原理在脚本中)
Is there any way to invoke a subprocess so that it and all its descendants are sent an interrupt, just as if you Ctrl-C a foreground task? I’m trying to kill a launcher script that invokes a long-running child. I’ve tried kill -SIGINT $child
(which doesn’t send the interrupt to its descendants so is a no-op) and kill -SIGINT -$child
(which works when invoked interactively but not when running in a script).
下面是一个测试脚本。在长时间运行脚本 test.sh --child
。当你调用 test.sh --parent
,它调用 test.sh --child&安培;
,然后尝试杀了它。我怎样才能让家长成功击杀了孩子?
Here’s a test script. The long-running script is test.sh --child
. When you call test.sh --parent
, it invokes test.sh --child &
and then tries to kill it. How can I make the parent kill the child successfully?
#!/bin/bash
if [ "$1" = "--child" ]; then
sleep 1000
elif [ "$1" = "--parent" ]; then
"$0" --child &
for child in $(jobs -p); do
echo kill -SIGINT "-$child" && kill -SIGINT "-$child"
done
wait $(jobs -p)
else
echo "Must be invoked with --child or --parent."
fi
我知道,你可以修改长时间运行的孩子陷阱
信号,将其发送到其子进程,然后等待(从
<一href=\"http://stackoverflow.com/questions/11696691/bash-script-kill-background-grandchildren-on-ctrlc\">Bash脚本杀背景(大)上按Ctrl + C 子女),但有什么办法,而无需修改脚本孩子?
I know that you can modify the long-running child to trap
signals, send them to its subprocess, and then wait (from
Bash script kill background (grand)children on Ctrl+C), but is there any way without modifying the child script?
推荐答案
阅读:<一href=\"http://stackoverflow.com/questions/2524937/how-to-send-a-signal-sigint-from-script-to-script-bash\">How从脚本发出一个信号SIGINT脚本? BASH
另外从信息庆典
To facilitate the implementation of the user interface to job control,
the operating system maintains the notion of a current terminal process
group ID. Members of this process group (processes whose process group
ID is equal to the current terminal process group ID) receive keyboard-
generated signals such as SIGINT. These processes are said to be in
the foreground. Background processes are those whose process group ID
differs from the terminal's; such processes are immune to keyboard-gen‐
erated signals.
所以庆典
的进程组ID 的区别,从前台进程后台进程。如果进程组ID 的等于的进程id 的,那么这个过程是一个前台进程,当它接收到 SIGINT <终止/ code>信号。否则,将不会终止(除非它被困住)。
So bash
differentiates background processes from foreground processes by the process group ID. If the process group id is equal to process id, then the process is a foreground process, and will terminate when it receives a SIGINT
signal. Otherwise it will not terminate (unless it is trapped).
您可以看到的进程组ID 的用
ps x -o "%p %r %y %x %c "
因此,当你运行一个后台进程(与&安培;
)的脚本中,它会忽略 SIGINT
信号,除非它被截留。
Thus, when you run a background process (with &
) from within a script, it will ignore the SIGINT
signal, unless it is trapped.
不过,你仍然可以杀死其他信号,如 SIGKILL
, SIGTERM
等子进程
However, you can still kill the child process with other signals, such as SIGKILL
, SIGTERM
, etc.
例如,如果你改变你的脚本下面就成功击杀子进程:
For example, if you change your script to the following it will successfully kill the child process:
#!/bin/bash
if [ "$1" = "--child" ]; then
sleep 1000
elif [ "$1" = "--parent" ]; then
"$0" --child &
for child in $(jobs -p); do
echo kill "$child" && kill "$child"
done
wait $(jobs -p)
else
echo "Must be invoked with --child or --parent."
fi
输出:
$ ./test.sh --parent
kill 2187
./test.sh: line 10: 2187 Terminated "$0" --child
这篇关于bash脚本如何能做到按Ctrl-C的一个后台任务等同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!