我循环运行我的命令。我将循环直接写入 bash 命令行:
$ while true; do mycommand; done
mycommand
是一个执行大量 io 并等待事件的命令,因此它不会消耗太多处理器时间。
我怎样才能中断循环?当我按下ctrl-c
或ctrl-\
然后我的命令被终止,但它立即再次启动。当我登录到另一个终端并杀死该命令时,情况是一样的。
是否可以在不终止终端会话的情况下中断循环?
答案1
杀死以交互方式启动的循环的一种足够简单的方法是停止命令 ( Ctrl- Z),该命令应该打印一个作业编号,例如[2]+ Stopped
,然后您可以使用 来终止该循环kill %2
。
答案2
你想要 ps -f。 pstree 也非常有用。查看 PPID(父 PID)。
$ps -f
UID PID PPID C STIME TTY TIME CMD
rui 7725 7722 0 13:30 pts/0 00:00:01 -bash
rui 8062 7725 0 14:09 pts/0 00:00:00 ps -f
$pstree-g
├─starter(1600)───charon(1603)─┬─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon} (1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ ├─{charon}(1603) │ └ ─{卡戎}(1603)
答案3
一点背景:
您的命令mycommand
在收到 SIGINT 时不会重新发送 SIGINT,而只是终止。因此,bash
运行循环的实例无法确定CTRL+C用于终止执行,并假设它只是您为 发出的键盘快捷键mycommand
。由于由于键盘快捷键(vi
例如想象一下使用)而终止 shell 是不可取的,因此bash
只需继续执行另一个循环迭代即可。
最终的解决方案是修复mycommand
,以便它在收到 SIGINT 时杀死自己,并让它bash
知道它也应该停止。
void sigint_handler(int sig)
{
// Execute your normal handler
signal(SIGINT, SIG_DFL); // don't catch the signal anymore
kill(getpid(), SIGINT); // kill itself with the same signal
}
来源:http://www.cons.org/cracauer/sigint.html
如果无法修复mycommand
,则必须关闭终端会话,或者按顺序终止bash
执行循环的进程和 的当前实例。mycommand