无法使用Ctrl + c终止shell命令

时间:2013-12-12 02:10:09

标签: bash shell terminate sigint

有人请告诉我为什么 Ctrl + c 无法正确终止bash语句?

$( { ( 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提示符。

我想要的是,输入 Ctrl + c ,然后退出bash提示,不需要任何相关流程。

有人会更好地解释这个陈述的确切过程,就像管道导致bash fork,某些东西重定向到某个地方等等。

于2014年10月9日更新:

这里提供一些更新,以防它对您有用。 我采用的解决方案与2个因素相似:

  1. 使用tmp pid文件

    ( tail -Fn0 ${monitor_file} & echo "$!" >${tail_pid} ) | \
    while IFS= read -r line; do 
        xxxx
    done 
    
  2. 使用陷阱如:trap "rm ${tail_pid} 2>/dev/null; kill 0 2>/dev/null; exit;" INT TERM来杀死相关进程并删除剩余文件。

  3. 请注意,此kill 0 2是特定于bash的,0表示当前进程组中的所有进程。 这个解决方案使用了tmp pid文件,而我仍然期望没有tmp pid文件的其他解决方案。

1 个答案:

答案 0 :(得分:1)

它可以捕获INT信号(由Ctrl-C发送)来杀死tail进程。

$( 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文件名上使用随机值,至少主要允许多个实例运行)