无法使用Ctrl + c终止Shell命令 [英] Cannot terminate a shell command with Ctrl+c
问题描述
有人可以告诉我为什么 Ctrl + c 不能正确终止bash
语句吗?
Would someone please tell me why below bash
statement cannot be terminated by Ctrl+c properly?
$( { ( tail -fn0 /tmp/a.txt & )| while read line; do echo $line; done } 3>&1 )
我运行此语句,然后启动两个bash
进程和一个tail
进程(从ps auxf
获取),然后输入 Ctrl + c ,它不会退出到在bash
提示符下,此时,我看到两个bash
进程停止了,而tail
仍在运行,然后在/tmp/a.txt
中输入了一些内容,然后我们进入了bash提示符.
I run this statement, then two bash
processes and one tail
process are launched(got from ps auxf
), then input Ctrl+c, and it won't quit to the bash
prompt, at this moment, I see the two bash
processes stopped, while the tail
is still running, then I input something into /tmp/a.txt
, then we could get into bash prompt.
我想要的是,输入 Ctrl + c ,然后直接退出bash
提示符而没有任何相关过程.
What I want is, input Ctrl+c, then just quit into bash
prompt without any relevant process left.
有人解释此语句的确切过程会更有意义,例如用管道导致bash分支,将某些内容重定向到某个地方等.
It will be more appreciative that someone explains the exact process of this statement, like a pipe causes the bash fork, something redirect to somewhere, etc.
2014年10月9日更新:
在此提供一些更新,以防对您有用. 我采用的解决方案与以下两个因素相似:
Here provide some update in case it's useful to you. My adopt solution is alike with 2 factors:
-
使用tmp pid文件
use a tmp pid file
( tail -Fn0 ${monitor_file} & echo "$!" >${tail_pid} ) | \
while IFS= read -r line; do
xxxx
done
使用陷阱,例如:trap "rm ${tail_pid} 2>/dev/null; kill 0 2>/dev/null; exit;" INT TERM
杀死相关进程并删除剩余文件.
use trap like: trap "rm ${tail_pid} 2>/dev/null; kill 0 2>/dev/null; exit;" INT TERM
to kill relevant processes and remove remain files.
请注意,此kill 0 2
是特定于bash的,0表示当前进程组中的所有进程.
此解决方案使用了tmp pid文件,而我仍然希望其他没有tmp pid文件的解决方案.
Please note, this kill 0 2
is bash specific, and 0 means all processes in the current process group.
This solution used a tmp pid file, while I still expect other solution without tmp pid file.
推荐答案
它可以捕获INT
信号(由Ctrl-C
发送)以杀死tail
进程.
It works to trap the INT
signal (sent by Ctrl-C
) to kill the tail
process.
$( r=$RANDOM; trap '{ kill $(cat /tmp/pid$r.pid);rm /tmp/pid$r.pid;exit; }' SIGINT EXIT; { ( tail -fn0 /tmp/a.txt & echo $! > /tmp/pid$r.pid )| while read line; do echo $line; done } 3>&1 )
(我在PID文件名上使用了随机值,至少在大多数情况下允许多个实例运行)
(I use a random value on the PID file name to at least mostly allow multiple instances to run)
这篇关于无法使用Ctrl + c终止Shell命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!