2012-02-22 131 views
0

我想處理每個標準輸出行的外殼,它創建的那一刻。我想抓取test.sh的輸出(一個漫長的過程)。我目前的做法是這樣的:殺死管道進程的好方法?

./test.sh >tmp.txt & 
PID=$! 
tail -f tmp.txt | while read line; do 
echo $line 
ps ${PID} > /dev/null 
if [ $? -ne 0 ]; then 
    echo "exiting.." 
fi 
done; 

但不幸的是,這將打印「退出」,然後等待,因爲尾-f仍在運行。我試過breakexit

我在FreeBSD上運行它,所以我不能使用某些linux尾部的--pid=選項。

我可以使用psgrep讓尾部的PID和殺死它,但是那似乎很醜陋的我。

任何提示?

回答

2

爲什麼你需要tail過程?

能代替你做一些沿

./test.sh | while read line; do 
    # process $line 
done 

行,或者,如果你想保持在tmp.txt輸出:

./test.sh | tee tmp.txt | while read line; do 
    # process $line 
done 

如果你仍然想使用一箇中間tail -f過程,也許你可以使用命名管道(fifo)而不是普通管道來允許分離tail進程並獲得其pid:

./test.sh >tmp.txt & 
PID=$! 

mkfifo tmp.fifo 
tail -f tmp.txt >tmp.fifo & 
PID_OF_TAIL=$! 
while read line; do 
    # process $line 
    kill -0 ${PID} >/dev/null || kill ${PID_OF_TAIL} 
done <tmp.fifo 
rm tmp.fifo 

但是我應該指出,這種解決方案具有的競爭條件幾種重金屬問題:

  • test.sh的PID會被其他進程重用;
  • 如果當你讀到最後一行test.sh過程還活着,你不會有任何其他場合事後發現它的死亡,你的循環將掛起。
+0

我現在感覺非常愚蠢的,作爲第一個解決方案顯然作品。我相對較新的shell腳本,並沒有意識到你提到的第一個解決方案不會阻止..謝謝! – RobAu 2012-02-22 16:59:33