.png)
rsyslog
特定のログ イベントを次のように記録するように構成しました/dev/xconsole
:
*.*;cron.!=info;mail.!=info |/dev/xconsole
/dev/xconsole
は名前付きパイプ ( fifo
) です。ログに記録されている内容を確認したい場合は、 を実行できます。コマンドはファイルを読み込んだ後も終了せず、 として動作することcat /dev/xconsole
に驚きました。つまり、2 つのコマンドの動作は同じです。cat /dev/xconsole
tail -f
cat /dev/xconsole
tail -f /dev/xconsole
誰かその理由を説明してくれませんか?
この2つには何か違いがありますか?
答え1
cat
EOFを取得するまで読み取りを続けます。パイプは入力でEOFを取得したときにのみ出力にEOFを生成します。ログデーモンはファイルを開いて書き込み、そしてそれを開いたままにしておく— 通常のファイルの場合と同じように — 出力に EOF が生成されることはありません。cat
パイプ内の現在内容がなくなるとブロックしながら読み取りを続けます。
これを手動で自分で試すこともできます:
$ mkfifo test
$ cat test
別のターミナルでは:
$ cat > test
hello
他のターミナルに出力が表示されます。次に、次のように入力します。
world
あるだろうもっと他の端末に出力します。ここで入力を Ctrl-D すると、他の端末cat
も終了します。
この場合、 と の唯一の目に見える違いは、cat
ログtail -f
記録デーモンが終了したか再起動されたかです。 は、cat
パイプの書き込み側が閉じられると永久に停止しますが、tail -f
デーモンが再起動されると続行されます (ファイルを再度開きます)。
答え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
標準出力に出力する前に行を最大 4kb までバッファリングすることがわかります。
答え3
cat
最後の行のみを表示し、それに続く場合はファイル全体が表示tail -f
されます。したがって、ファイルが短い場合は同じように動作しますが、ファイルが大きい場合 (100 行以上)、2 つの間に明確な違いが見られます。
これらのコマンドに関する追加情報: