特定の出力が生成されると、プロセスを終了します。

特定の出力が生成されると、プロセスを終了します。

プログラムを実行していますが(ほとんど)正しく実行されますが、中断されます。特定の文字列を出力したり、出力の生成を中止した直後にプログラムが終了するようにプログラムを実行したいと思います。

私が興味のある出力文字列は次のとおりです。

Was exported to:

この出力を見た後、プログラムを自動的に終了したいと思います。または、その後、プログラムは出力の生成を中断するため、その条件に応じてプログラムを終了できます。これらのいずれかをどのように実装できますか?

答え1

Process substitution1つのオプションは、このツールをgrepとして実行することです。

grep -m 1 "Was exported to:" <(<command>)

最初の一致後に実行を停止するようgrepに指示します-m 1。実行が停止すると、内部コマンド<( ... )も終了します。しかし、私の考えでは、これは少し「醜い」です。

それでも使用されますが、grep内部でコマンドを実行することなく出力をファイルにリダイレクトし、バックグラウンドで実行し、プロセスを使用してファイルを読み取りtail -Fgrep出力し、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

関連情報