特定のログイベントを/dev/xconsole
に記録するようにrsyslog
を設定しました:
*.*;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つの間に違いはありますか?
cat
は、EOFになるまで読み取りを続けます。パイプがEOFを取得するのは、入力でEOFを取得した場合のみです。ロギングデーモンがファイルを開いて書き込みを行っていますそして、それを開いたままにします —通常のファイルの場合と同様に— EOFは出力で生成されることはありません。cat
は読み取りを継続し、現在パイプ中です。
手動でこれを試すことができます:
$ mkfifo test
$ cat test
そして別のターミナルで:
$ cat > test
hello
他の端子に出力されます。次に:
world
他の端末にはmoreの出力があります。ここで入力をCtrl-Dすると、他のcat
も終了します。
この場合、cat
とtail -f
の唯一の観察可能な違いは、ロギングデーモンが終了または再起動された場合です。cat
は、パイプの書き込み側が閉じられると永久に停止します、ただしtail -f
は、デーモンが再起動されても続行します(ファイルを再度開きます)。
cat
と_tail -f
_の間にはbufferingの違いもあります。あなたはこれをチェックすることができます:
パイプを作成:_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}'
cat
の代わりに_tail -f pipe &
_でこれを試してください。したがって、cat
は、Perlスクリプトによってパイプに書き込まれるとすぐに行を出力し、_tail -f
_は、標準出力に出力する前に最大4kbをバッファリングすることがわかります。