プログラムを実行していますが(ほとんど)正しく実行されますが、中断されます。特定の文字列を出力したり、出力の生成を中止した直後にプログラムが終了するようにプログラムを実行したいと思います。
私が興味のある出力文字列は次のとおりです。
Was exported to:
この出力を見た後、プログラムを自動的に終了したいと思います。または、その後、プログラムは出力の生成を中断するため、その条件に応じてプログラムを終了できます。これらのいずれかをどのように実装できますか?
答え1
Process substitution
1つのオプションは、このツールをgrepとして実行することです。
grep -m 1 "Was exported to:" <(<command>)
最初の一致後に実行を停止するようgrepに指示します-m 1
。実行が停止すると、内部コマンド<( ... )
も終了します。しかし、私の考えでは、これは少し「醜い」です。
それでも使用されますが、grep
内部でコマンドを実行することなく出力をファイルにリダイレクトし、バックグラウンドで実行し、プロセスを使用してファイルを読み取りtail -F
、grep
出力し、kill
最初の一致後に出力します。
COMMAND > $OUTPUTFILE & tail --pid=$! -n +1 -F $OUTPTFILE | (grep -q -m 1 "Was exported to:" && kill $!)
これは、プロセスが完了または終了したときに実行も停止するよう--pid=$!
にするためです。tail
grep
ただし、どちらの方法も、実行中の行の後に改行文字が続く場合にのみ機能します。
答え2
次のことができます。
sh -c 'echo "$$"; exec stdbuf -oL "$0" "$@"' my-program with its args | (
IFS= read -r pid &&
sed '/Was exported to:/q' &&
kill -s PIPE "$pid"
)
ラインベースのバッファリング(アプリケーションはブロックバッファリングを実行する傾向があります)を復元するために、以前にmy-program
実行したプロセス(GNUまたはFreeBSDベースのシステムで見つかりました)と同じプロセスを実行し、sh
そのpidをパイプに送信します。stdbuf -oL
端末に送信されます)
パイプの反対側の端でsed
待つと、最初にuitが表示されますWas exported to:
。q
その後、SIGPIPE信号がpidに送信され、プロセスは終了します。これがなければ、SIGPIPEはkill
終了my-program
後にパイプに書き込むときにのみ受信されます。grep