web-dev-qa-db-ja.com

名前付きパイプにEOFを送信-fifoのクリーンアップ/乾燥

名前付きパイプから読み取るランダムプロセスがある場合:

tail -f MYNAMEDPIPED 
cat MYNAMEDPIPE | someOtherProc

他の場所では、MYNAMEDPIPEDを名前で処理しています。 MYNAMEDPIPEDを削除することによって、またはおそらく「乾燥させる」ことによってテールプロセスを停止する安全でクリーンな方法はありますか?

言い換えると

MYNAMEDPIPED.noMoreDataIsComingThroughSoPleaseStopTailingThis()

:)

コメントの1つから、EOF=をMYNAMEDPIPEに送信するように言われています。しかし、これを行う方法がわかりません。

これは私が直面している困難を示しています:

http://comp.os.linux.questions.narkive.com/2AW9g5yn/sending-an-eof-to-a-named-pipe

5
Alexander Mills

EOFは文字ではありませんでも「イベント」でもないため、パイプを介して送信したり、執筆の終わりまで「供給」したりできませんでした。

only pipe/fifoの読み取り側でEOFを生成する方法(つまり、read(2)で0を返す)は、開いているすべてを閉じることです書き込み終了まで処理します。

これは、名前付きパイプを書き込みモードで開いたすべてのプロセスと、fork()を介してファイル記述子を継承したすべての子が終了すると、自動的に発生します[1]。

名前付きパイプのread(2)は、パイプが読み取り/書き込みモードで開かれている場合、0を返すことはできません。と

_exec 7<>/path/to/fifo
_

その場合、パイプの両端に単一のファイル記述子/ハンドルがあり、書き込み端を閉じると、読み取り端も閉じ、read(2)が0を返すことができなくなるためです(パイプはどの種類もサポートしていません)ソケットがshutdown(2))で行うように、ハーフクローズの。

[1]そして、UNIXソケットで_SCM_RIGHTS_補助メッセージを介してファイル記述子を受け取ったすべてのプロセス。


_tail -f_の定義は、読み取り元のファイルが通常のファイルでも特別なファイルでも、EOFで終了しないことに注意してください。ファイル記述子へのオープンハンドルを保持しているすべてのプロセスを強制終了する1つの方法は、fuser(1)を使用することです。

_tail -f /path/to/fifo
...
> /path/to/fifo  # let any blocking open(2) through
fuser -TERM -k /path/to/fifo
_

これは、親から_/path/to/fifo_へのオープンハンドルを(不注意に)継承したプロセスも強制終了することに注意してください。

5
mosvy

「EOFを送信」することはできません。パイプを通過する「EOF文字」はありません。

通常、Linuxプログラムは、ブロッキングモードでread(2)を使用してファイル記述子から読み取り、受信したデータでバッファを満たし、読み取った文字数を返します。 readが0を返した場合、つまり0バイトが読み取られた場合、ほとんどのプログラムはこれをファイルの終わりと解釈します。

プログラムは、fsync(2)を使用して、バッファがいっぱいになる前にパイプの側面をフラッシュできます。その場合、リーダーのreadは、バッファーが空の場合でもすぐに返され、readbytesの量として0が返されます。

これは、catを実行し、いくつかの文字(リターンではない)を入力して、Ctrl-Dキーを押すと(ターミナルによってフラッシュされる)、観察できます。そのとき、catは入力された文字を出力します。もう一度Ctrl-Dを押すと、catreadは0バイトを返し、catがファイルの終わりに達したと見なします。ラインバッファリングが使用されるため、Returnキーを押すと、catはその入力も出力します。

1
stefan