fifoで入力をリダイレクトするときにstdoutがフラッシュされないのはなぜですか?

fifoで入力をリダイレクトするときにstdoutがフラッシュされないのはなぜですか?

プロンプトメッセージを表示し、ユーザーがテキストを入力するのを待つプログラムがあります。

$ program
Input a line of text: <aaaa>
Some more output.
$

次のように、FIFOを介してプログラムでこの入力を提供できるようにしたいと思います。

$ program < fifo

ただし、.stdoutに入力を提供するまでプロンプトは表示されませんfifo

次に私は私のプログラムと非常に簡単に同等のものを試しました。それは次のとおりです。

$ echo aaaa < fifo

ここでもaaaa入力が提供されるまで表示されません。fifo

質問:stdinFIFOを使用するときに入力が来るまで出力を待つにはどうすればよいですか?stdout

ベストアンサー1

FIFO はシェルによって開かれますが、他のプロセスで書き込むために FIFO を開くまで、その起動はブロックされます。リダイレクトが処理されるため今後コマンドが実行された後は、シェル呼び出しが返されるまでプログラムは実行されませんopen()。これは文書化された動作です。Copen()ライブラリ関数(シェルで使用):

O_NONBLOCK

O_RDONLY以下を有効または設定してFIFOをオンにしたときO_WRONLY

  • O_NONBLOCK設定されている場合、open()読み取り専用がすぐに返されます。open()現在読み取るためにファイルを開いたプロセスがない場合、書き込み専用はエラーを返します。

  • O_NONBLOCK消すならopen()読み取り専用 呼び出しスレッドは、スレッドが書き込み用にファイルを開くまでブロックする必要があります。。書き込み専用の場合は、スレッドがopen()読み取り用にファイルを開くまで呼び出しスレッドをブロックする必要があります。

したがって、シェルはO_NONBLOCKFIFOを開くときには明らかにそれを使用しません。

解決策:

  1. cat fifo | program

    catFIFOからファイルの最後まで読み取って終了します。

  2. tail -f fifo | program

    tailファイルが終了するまでFIFOから読み込み、終了するまでより多くのコンテンツを待って停止します。

これらのうち、あなたの状況に最も適したものは、部分的に相手がFIFOに書き込む内容と作成方法によって異なります。

3番目の解決策は、必要に応じてプログラムにFIFOを開くようにすることです。


~によると基本原理部分sh、シェルは標準入力をブロックに設定する必要があります。なぜなら…

シェルがこのフラグをリセットしないと、入力データがまだ利用できないためすぐに終了し、ファイルの終わりと同じように処理されます。

おすすめ記事