名前付きパイプから継続的に読み取る(catまたはtail -f)

名前付きパイプから継続的に読み取る(catまたはtail -f)

rsyslogいくつかのログイベントが記録されるように設定しました/dev/xconsole

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

/dev/xconsole名前付きパイプ(fifo)。録画された内容を見たい場合は、これを行うことができますcat /dev/xconsolecat /dev/xconsoleファイルを読み取った後、コマンドは完了せずに代わりにtail -f。つまり、両方のコマンドが同じように動作するという事実に驚きました。

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

誰かがこれがなぜ説明できますか?

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

答え1

catEOFに達するまで読んでください。パイプが入力からEOFを取得した場合にのみ、出力からEOFを生成します。ログデーモンがファイルを開いて書き込んでいます。そして開いたままにしてください- 通常のファイルと同様 - 出力にEOFは生成されません。cat読み続けながら、パイプの現在のコンテンツがなくなるたびにブロックします。

手動で試してみることができます。

$ mkfifo test
$ cat test

他の端末から:

$ cat > test
hello

他の端末に出力があります。次に、次のように入力します。

world

ありますもっと他の端末に出力します。 Ctrl-Dを押して入力すると、他の入力catも終了します。

catこの場合、willとwillの間で観察できる唯一の違いは、tail -fロギングデーモンが終了するのか再起動されるのかということです。catパイプの書き込み側が閉じると永久に停止しますが、tail -fデーモンが再起動された後も実行されます(restart open)ファイル)。

答え2

別の違いはバッファー間。以下を見ることcatができますtail -f

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

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

パイプを開き、毎秒以下を作成します。perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

tail -f pipe &では、代わりに試してみてください。 Perlスクリプトがパイプにラインを書き込むと、stdoutで印刷する前に最大4kbまでバッファリングしながら印刷するcatことがわかります。cattail -f

答え3

cattail -f最後の行と次の行のみが表示されたときにファイル全体を表示します。したがって、ファイルが短い場合は同じように動作しますが、ファイルが大きい場合(100行以上)、2つの間に明らかな違いがあることがわかります。

これらのコマンドに関する追加情報:

tail http://www.computerhope.com/unix/utail.htm

cat http://www.computerhope.com/unix/ucat.htm

関連情報