2012-02-22 7 views
0

シェル用に各stdout-lineを処理したいときは、それを作成します。私は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プロセスが必要ですか?

あなたはtmp.txtで出力を維持したい場合は、代わりに

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

か、の線に沿って何かを行うことができます:

./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

最初の解決策が明らかにうまくいきましたので、今は本当に馬鹿げています。私はシェルスクリプトには比較的新しいので、あなたが言及した最初の解決策がブロックされていないことを認識していませんでした。ありがとう! – RobAu

関連する問題