dmsg` の出力を `tail -f` することは可能か。
dmesg | tail -f
みたいなことをしたいのですが、うまくいきません。
Mac OS X v10.6.7 (Snow Leopard)を使用しています。そうすることで、tail
は出力を監視するのではなく、終了してしまいます。
何か方法があるのか、それに相当するコマンドがあるのかな。
追伸、while
のループではダメだと思います。
dmesg | tail -f
みたいなことをしたいのですが、うまくいきません。
Mac OS X v10.6.7 (Snow Leopard)を使用しています。そうすることで、tail
は出力を監視するのではなく、終了してしまいます。
何か方法があるのか、それに相当するコマンドがあるのかな。
追伸、while
のループではダメだと思います。
おそらく、様々なログファイルからのメッセージの組み合わせを探しているのでしょう。試してみてください。
tail -f /var/log/{messages,kernel,dmesg,syslog}
…を試してみてください。それ以上でもそれ以下でも良いのであれば、見たいメッセージがどのログファイルに置かれているかを調べてみてください。
また、multitail
を使って、一度に複数のログファイルをファイル化してカラーコード化したり、フィルタリングしたりすることも検討してみてください。
編集:これに答えたときにはあまり関係のないことでしたが、このページは多くのヒット数を獲得しているので、systemdを実行している新しいシステムにはこのような機能があることに言及する価値があると思いました。
dmesg -w
man dmesg
参照) /proc/kmsg
(man proc
参照) /proc/kmsg
を直接読む、つまり cat /proc/kmsg
を読む。さて、親切な proc マニュアルを読むと、一度に一人のユーザ(特権を持っている必要があります)だけに /proc/kmsg
を読ませるようにと厳しく警告されています。あなたが持っているどのような syslog 実装でも、これを行うべきであり、おそらく dmesg
で動作するはずです。分からないが、マニュアルの言い換えをしただけで、私はここでは私の領域外にいる。だから、これは「とにかく@#$%%ingを動作させる」方法ですが、最初に次の2つのメソッドを考えてみてください。
私がsystemd init*で使っているlinuxボックスでは、dmesg.logはあまり書き込まれていません。カーネルログバッファを継続的に読むための最良の方法は、watch
を使うことです。
watch 'dmesg | tail -50'
もっと複雑な解決策としては、ウォッチを使ってdmesgの出力をファイルに書き込んで、それをtail -f
するという方法があるかもしれません。おそらく、これはデーモンとして実行したいと思うでしょう。適切なデーモンはログを gzip して回転させることもできます。以下の bash コードはテストされておらず、動作しておらず、アイデアを伝えるためだけのものです。Brooks Mosesさんの回答には、作業用バージョンがあります。
watch 'dmesg >> /var/log/dmesg.log | tail -1'
0x1&
* tangent, なぜなら、これはアップルのデスクトップOSについての質問なので: systemdがあるときは、dmesg
を気にしないでください; journalctl -xf
を使ってください (たぶん、前の100行を表示するために-n 100
を使う)
以下は djeikyb の回答 の変形版で、実際にテストされており、いくつかのバグを修正しています。
watch 'sudo dmesg -c >> /tmp/dmesg.log; tail -n 40 /tmp/dmesg.log'
重要なトリックは、印刷後にリングバッファをクリアするdmesg -c
を行っていることです。
これを行うには root である必要があります。また、出力をファイルにダンプしてtailにパイプする(これはうまくいきません)代わりに、新しく書き込まれたファイルから読み出すというバグフィックスもあります。
sudo
だけを実行して、反復するたびにファイル全体を上書きすることもできますが、これは多くのI/Oを必要としますし、上書きの途中でコンピュータがクラッシュした場合にファイルを失うリスクもあります。
また、dmesg > /tmp/dmesg.log
とtail -f
を永遠に実行するwhile
ループを使ってdmesg -c
に近いことをすることもできます(Ben Harrisの回答を参照)。しかし、これは実際には実行中にカーネルメッセージバッファをクリアしているので、後で必要になった場合に備えてログファイルにパイプしておくと良いでしょう。
この投稿を見る前にやってしまいました。
#!/usr/bin/env perl
use strict;
use warnings;
# "tail -f" for dmesg
# Keeps last printed line. Anything sorting "gt" will be newer
$|=1;
my $y = '';
while(1) {
for my $k (`dmesg`) {
if ($k gt $y) {
print $k;
$y = $k;
}
}
sleep 1;
}
exit;
組込み環境やプリブート環境のように、watch, tail, cat, dd などのコマンドが利用できない環境では、別の工夫が必要になるかもしれません。
while dmesg -c >> /tmp/dmesg.log; do sleep 0.1; done & tail -f /tmp/dmesg.log
これは、生成された出力を尾行しながら(&を使って)whileループを背景にしています。
mount -t tmpfs - /tmp
# or
mount -t ramfs - /tmp
# or use /dev/shm instead of /tmp - which is available in newer environments
/tmp に書き込めない場合。
cat /tmp/dmesg.log
# or
dd if=/tmp/dmesg.log
# or
dd if=/tmp/dmesg.log 2>/dev/null
busybox dmesg -c
テールがない場合は、
busybox sleep
もしくは、dmesgがリンクされていないビジーボックス環境にいるかもしれません。
while dmesg -c; do echo >/dev/null; done
sleep の代わりに
while sleep 0.1; do cat -v /proc/kmsg; done
sleep が必要な場合もあります。
busybox ls
# or simply:
echo *
これは、他に何も読み込んでいない場合にのみ動作します。また、「/dev/kmsg」があるかもしれません。
何を持っているかわからず、"ls" を持っていない場合は、次のようにしてください。
現在のUbuntu( Ubuntu 12.04 (Precise Pangolin)を使用しています)では、
tail -f /var/log/syslog
6< <( cat /var/log/syslog |grep -F 'kernel: '; sudo cat /proc/kmsg) cat /dev/fd/6
(sudoコマンドはsudo権限が必要です)
他のものも試してみてください。6< <( dmesg; sudo cat /proc/kmsg) cat /dev/fd/6
これは便利かもしれません。
dmesg | tail -f -
は、標準出力へのショートカットとして dmesg
演算子を使用して、-
の出力を tail にパイプします。