问题
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 )
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.
What I want is, input Ctrl+c, then just quit into bash
prompt without any relevant process left.
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.
Updated at Oct 9 2014:
Here provide some update in case it's useful to you. My adopt solution is alike with 2 factors:
use a tmp pid file
( tail -Fn0 ${monitor_file} & echo "$!" >${tail_pid} ) | \ while IFS= read -r line; do xxxx done
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.
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.
回答1:
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 )
(I use a random value on the PID file name to at least mostly allow multiple instances to run)
来源:https://stackoverflow.com/questions/20533745/cannot-terminate-a-shell-command-with-ctrlc