名前付きパイプからの連続読み取り(catまたはtail -f)


16

rsyslog特定のログイベントを記録するように設定しました/dev/xconsole

*.*;cron.!=info;mail.!=info      |/dev/xconsole

/dev/xconsole名前付きパイプ(fifo)です。ログに記録されているものを確認したい場合は、できますcat /dev/xconsole。コマンドcat /dev/xconsoleがファイルの読み取り後に終了せず、代わりにとして機能することを見て驚いていますtail -f。つまり、2つのコマンドは同じように動作します。

cat /dev/xconsole
tail -f /dev/xconsole

誰かがその理由を説明してもらえますか?

2つの間に違いはありますか?

回答:


18

catEOFを取得するまで読み続けます。パイプは、入力でEOFを取得した場合にのみ出力でEOFを生成します。ロギングデーモンは、ファイルを開いて書き込み、通常のファイルの場合と同じように開いたままにしているため、出力にEOFが生成されることはありません。cat読み取りを続け、パイプ内に現在あるものを使い果たすたびにブロックします。

手動でこれを試すことができます:

$ mkfifo test
$ cat test

そして、別のターミナルで:

$ cat > test
hello

他の端末に出力があります。次に:

world

他の端末にはさらに出力があります。ここで入力をCtrl-Dすると、もう一方catも終了します。

この場合は、間の唯一の観察可能な違いcatとはtail -f:ログ・デーモンが終了または再起動した場合になりますcatパイプの書き込み側が閉じられたときに永久に停止しますが、tail -fデーモンが再起動したときに行く(ファイルを再開)し続けます。


ごめんなさい、あなたの例では「世界」がどこから来るのかわかりません:)
アレクサンダーミルズ

あなたのタイピングから、それインチ
マイケル・ホーマー

1
次にworld、と入力すると、もう一方の端末に「world」と表示されます。
マイケル・ホーマー

2

との間のバッファリングにも違いがcatありtail -fます。これを確認できます:

パイプを作成します。 mkfifo pipe

catバックグラウンドで使用してパイプの読み取りを開始します。cat pipe &

パイプを開いて、毎秒書き込みます: perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

tail -f pipe &では、の代わりにこれを試してくださいcat。したがってcat、perlスクリプトによってパイプに書き込まれるとすぐに行tail -f が出力され、stdoutに出力する前に最大4kbでバッファリングされることがわかります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.