1

有人能告诉我为什么bash不能Ctrl+c正确终止以下语句吗?

$( { ( 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 分叉,某些东西重定向到某个地方等等。

2014 年 10 月 9 日更新:

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

  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杀死相关进程并删除剩余文件。

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

4

1 回答 1

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 文件名上使用了一个随机值,至少大多数情况下允许多个实例运行)

于 2014-01-02T08:29:23.437 回答