2013-12-12 34 views
1

請問有人請告訴我爲什麼在bash以下不能終止語句Ctrl + c正確嗎?無法用Ctrl + c終止一個shell命令

$({ (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叉,什麼重定向到某個地方,等

在10月9日更新日期:2014:

這裏提供一些更新,以防它對你有用。 我採取的解決方案是,都與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殺死相關進程和刪除保持文件。

請注意,這個kill 0 2是bash特有的,0表示當前進程組中的所有進程。 這個解決方案使用了一個tmp pid文件,而我仍然期望沒有tmp pid文件的其他解決方案。

+1

你爲什麼與'$(...)'運行呢?這是爲了替換命令。 – Barmar

+0

「tail -fn0 /tmp/a.txt&」在後臺啓動一個新進程(由於&),所以它不受主進程的ctrl + c影響。 – user2196728

+1

http://explainshell.com/explain?cmd=%28%7B+%28+tail+-fn0+%2Ftmp%2Fa.txt+%26+%29%7C+while+read+line%3B+do+echo+%24line %3B + done +%7D + 3%3E%261%3B%7D%29 – Logan

回答

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文件名隨機值至少大部分允許多個實例運行)