bash脚本如何能做到按Ctrl-C的一个后台任务等同? [英] How can bash script do the equivalent of Ctrl-C to a background task?

查看:181
本文介绍了bash脚本如何能做到按Ctrl-C的一个后台任务等同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有什么办法来调用一个子进程,使它和它的所有后代都发出了中断,就像如果你按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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆