Bashの組み込み機能がパイプでどのように機能するか

Bashの組み込み機能がパイプでどのように機能するか

吹く組み込み定義ように:

シェルは他のプログラムを呼び出さずに直接コマンドを実行します。

このようなパイプラインはfoo | barおおよそ次のように動作します。barの入力を待ってfooからfoo終了しますbar

Bashでは、これらのパイプラインは期待どおりに機能します。

$ history | grep curl

しかし、タスクが完了し、それ自体で終了することをどのようにgrep知ることができますか?組み込みプロセスなので、新しいプロセスは作成されませんhistory。信号を生成historyしますか?historyEOF

ベストアンサー1

マニュアルに「他のプログラムを呼び出さないでください」と書かれている場合、シェルは他のプログラムをexecve実行するために使用されないことを意味します。コマンドがリダイレクトを使用する場合、簡単な実装はfork別のプロセスに移動し、親シェルのファイル記述子を変更せずにそのプロセスのみをリダイレクトすることです。これはbashこのコマンドが実行するアクションであると確認することもできますstrace

内部コマンドブランチを回避するために実行できるトリックがいくつかありますが、この場合は使用されないようです。

2番目のプログラムは、1番目のプログラムが終了したことを検出できず、パイプの出力端が閉じていることのみを検出できます(これはプログラムが終了したか一般的なものである可能性がありますclose)。パイプの読み取り端はEOFを受け取ります。

パイプラインの最初のプログラムが最初に終了するのが一般的ですが、必ずしもそうではありません。考えてみてください:

sleep 10 | echo done

パイプの2番目のプログラムが最初のプログラムの前に終了し、最初のプログラムがパイプに書き込もうとするとシグナルをSIGPIPE受け取ります。

(sleep 10; echo test ) | echo done

おすすめ記事