2011-05-26 21:55:11 +0000 2011-05-26 21:55:11 +0000
146
146

Ist es möglich, die Ausgabe von `dmesg` mit `tail -f` zu versehen?

Ich möchte etwas wie

dmesg | tail -f

machen, aber es funktioniert nicht:

Ich verwende Mac OS X v10.6.7 (Snow Leopard). Wenn ich das tue, wird tail beendet, anstatt die Ausgabe zu überwachen.

Ich frage mich, ob es eine Möglichkeit gibt, dies zu tun, oder einen gleichwertigen Befehl.

P.S., ich glaube nicht, dass eine while-Schleife eine gute Idee ist.

Antworten (11)

130
130
130
2011-05-26 22:04:06 +0000

Sie suchen wahrscheinlich nach einer Kombination von Meldungen aus verschiedenen Protokolldateien. Versuchen Sie es:

tail -f /var/log/{messages,kernel,dmesg,syslog}

…um einen ziemlich guten Überblick über das System zu bekommen. Wenn Sie mehr oder weniger als das wollen, recherchieren Sie, in welcher Protokolldatei die Meldungen, die Sie sehen wollen, abgelegt werden.

Sehen Sie sich auch die Verwendung von multitail an, um mehrere Protokolldateien auf einmal zu archivieren und farblich zu kodieren und zu filtern.

Edit: Dies war nicht sehr relevant, als ich diese Frage beantwortete, aber da diese Seite eine Menge Treffer erhält, dachte ich, es sei erwähnenswert, dass neuere Systeme, auf denen systemd läuft, dies haben.

dmesg -w
56
56
56
2011-06-11 22:42:51 +0000

Just make it @#$%ing work

  1. Sie wollen die Ausgabe von dmesg drucken, ständig, sofort
  2. Dmesg druckt den Kernel-Ringpuffer (siehe man dmesg)
  3. Der Kernel-Ringpuffer ist eine spezielle proc-Datei, /proc/kmsg (siehe man proc)
  4. Lesen Sie /proc/kmsg direkt, also cat /proc/kmsg.

Nun, wenn Sie das freundliche Proc-Handbuch lesen, wird es Sie eindringlich davor warnen, nur einen Benutzer (der privilegiert sein muss) /proc/kmsg gleichzeitig lesen zu lassen. Welche Syslog-Implementierung Sie auch immer haben, sie sollte das tun, und vermutlich funktioniert sie mit dmesg. Ich weiß nicht, ich bin hier außerhalb meiner Liga, ich paraphrasiere nur das Handbuch. Während dies also der “Lass es einfach @#$%ing funktionieren”-Weg ist, sollten Sie zuerst die nächsten paar Methoden in Betracht ziehen.

Man page approved: watch + dmesg

Auf einer Linux-Box, die ich mit systemd init* verwende, wird dmesg.log nicht sehr oft geschrieben, vielleicht gar nicht? Die beste Methode, die ich gefunden habe, um den Kernel-Log-Puffer kontinuierlich zu lesen, ist mit watch. So etwas sollte Ihnen den Einstieg erleichtern (passen Sie an, wie viele Zeilen in Ihr Terminal passen):

watch 'dmesg | tail -50'

watch + dmesg + daemon + tail -f

Eine etwas kompliziertere Lösung könnte watch verwenden, um die dmesg-Ausgabe in eine Datei zu schreiben, die Sie dann tail -f. Sie würden dies wahrscheinlich als Daemon laufen lassen wollen. Ein richtiger Daemon würde auch gzip und Logs rotieren. Der folgende Bash-Code ist ungetestet, nicht funktionierend und soll nur eine Idee vermitteln. Die Antwort von @Brooks Moses hat eine funktionierende Version .

watch 'dmesg >> /var/log/dmesg.log | tail -1'

* Tangente, weil dies eine Frage über ein Apple-Desktop-Betriebssystem ist: wenn systemd in der Nähe ist, machen Sie sich nicht die Mühe mit dmesg; verwenden Sie journalctl -xf (vielleicht mit -n 100, um auch die vorherigen 100 Zeilen anzuzeigen)

47
47
47
2014-03-28 14:27:08 +0000

Unter Linux, seit Kernel 3.5.0 können Sie verwenden:

dmesg -w

Auch auf Systemen mit systemd können Sie verwenden:

journalctl -kf
21
21
21
2012-07-20 21:45:27 +0000

Hier ist eine Variante von djeikybs Antwort , die tatsächlich getestet wurde und ein paar Fehler behebt.

watch 'sudo dmesg -c >> /tmp/dmesg.log; tail -n 40 /tmp/dmesg.log'

Der wichtige Trick ist, dass wir dmesg -c machen, was den Ringpuffer nach dem Drucken löscht - so drucken wir jedes Mal nur das, was seit dem letzten Mal neu ist.

Sie müssen root sein, um das zu tun, daher das sudo. Es gibt auch eine Fehlerbehebung; anstatt zu versuchen, die Ausgabe sowohl in eine Datei zu schreiben als auch nach tail zu leiten (was nicht funktioniert), lesen wir nur aus der neu geschriebenen Datei.

Wir könnten einfach dmesg > /tmp/dmesg.log machen und die ganze Datei bei jeder Iteration überschreiben, aber das ist eine Menge E/A und birgt auch das Risiko, die Datei zu verlieren, wenn der Computer mitten im Überschreiben abstürzt.

Sie könnten auch etwas Ähnliches machen, das eher wie tail -f ist, mit einer while-Schleife, die dmesg -c und sleep 1 für immer ausführt (siehe die Antwort von Ben Harris). Da dies jedoch tatsächlich den Kernel-Meldungspuffer löscht, während er läuft, möchten Sie die Dinge vielleicht auch in eine Protokolldatei leiten, falls Sie sie später benötigen.

5
5
5
2012-11-05 13:45:51 +0000

Ich habe dies getan, bevor ich diesen Beitrag gesehen habe:

#!/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;
3
3
3
2013-03-05 08:26:53 +0000

Hier sind einige Ideen für eingeschränkte Umgebungen

Umgebungen wie eingebettete oder Pre-Boot-Umgebungen, in denen watch, tail, cat, dd und andere Befehle möglicherweise nicht verfügbar sind, benötigen möglicherweise andere Gymnastik.

So machen es einige leichtgewichtige Linux-Distributionen:

while dmesg -c >> /tmp/dmesg.log; do sleep 0.1; done & tail -f /tmp/dmesg.log

Sie unterdrücken die while-Schleife (mit &), während sie die erzeugte Ausgabe mit tail versehen.

Wenn Sie nicht nach /tmp schreiben können:

mount -t tmpfs - /tmp 

# or 
mount -t ramfs - /tmp 

# or use /dev/shm instead of /tmp - which is available in newer environments

Wenn Sie kein tail haben, können Sie

cat /tmp/dmesg.log

# or 
dd if=/tmp/dmesg.log 

# or
dd if=/tmp/dmesg.log 2>/dev/null

Oder Sie sind vielleicht in einer Busybox-Umgebung, die dmesg nicht verlinkt hat, dann einfach:

busybox dmesg -c

Sie könnten auch

busybox sleep

anstelle von sleep

benötigen. Wenn Sie sleep nicht haben:

while dmesg -c; do echo >/dev/null; done

Wenn Sie “dmesg” nicht haben:

while sleep 0.1; do cat -v /proc/kmsg; done

Dies funktioniert nur, wenn nichts anderes von hier gelesen wird. Möglicherweise haben Sie auch ein /dev/kmsg.

Bonustipp:

Wenn Sie nicht wissen, was Sie haben, und Sie kein “ls” haben, einfach:

busybox ls

# or simply:

echo *
3
3
3
2011-05-26 22:01:52 +0000

Möglicherweise können Sie Folgendes tun:

tail -f /var/log/messages
3
3
3
2016-02-04 09:16:00 +0000

Ich verwende diesen Alias in /root/.bashrc;

alias dwatch='watch -n 0.1 "dmesg | tail -n $((LINES-6))"'

, der dmesg folgt und die Zeilen für das jeweilige Terminal anpasst, in dem es aufgerufen wird.

0
0
0
2012-12-17 04:37:01 +0000

Unter dem aktuellen Ubuntu (ich verwende 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

( der sudo-Befehl benötigt sudo-Rechte )

Bitte versuchen Sie auch einen anderen wie: 6< <( dmesg; sudo cat /proc/kmsg) cat /dev/fd/6

0
0
0
2016-01-22 22:49:10 +0000

Ich habe diesen Code verwendet, um nach einem speziellen Kernel-Ereignis zu suchen und es einem “Callback”-Prozess zu übergeben:

while true ; do dmesg -c ; sleep .1 ; done \
| grep --line-buffered -o $pattern \
| ...
-3
-3
-3
2014-01-15 08:08:27 +0000

Dies könnte nützlich sein:

dmesg | tail -f -

leitet die Ausgabe von dmesg durch tail und verwendet dabei den Operator - als Abkürzung für die Standardausgabe.