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

Is het mogelijk om `tail -f` de uitvoer van `dmesg`?

Ik wil iets doen als

dmesg | tail -f

maar het werkt niet:

Ik gebruik Mac OS X v10.6.7 (Snow Leopard). Door dat te doen, zal tail afsluiten, in plaats van de uitvoer te controleren.

Ik vraag me af of er een manier is om dit te doen, of een gelijkwaardig commando.

P.S., ik denk niet dat een while loop een goed genoeg idee zal zijn.

Antwoorden (11)

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

U bent waarschijnlijk op zoek naar een combinatie van berichten uit verschillende logbestanden. Probeer eens:

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

…om een vrij goed overzicht van het systeem te krijgen. Als je meer of minder dan dat wilt, onderzoek dan in welk logbestand de berichten die je wilt zien worden geplaatst.

Kijk ook eens naar het gebruik van multitail om meerdere logbestanden tegelijk te fileeren, te colorcoden en te filteren.

Edit: Dit was niet erg relevant toen ik dit antwoord gaf, maar omdat deze pagina veel hits krijgt vond ik het de moeite waard om te vermelden dat nieuwere systemen met systemd dit hebben.

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

Just make it @#$%ing work

  1. Je wilt de uitvoer van dmesg afdrukken, constant, onmiddellijk
  2. Dmesg drukt de kernel ring buffer af (zie man dmesg)
  3. De kernel ring buffer is een speciaal proc bestand, /proc/kmsg (zie man proc)
  4. Lees /proc/kmsg rechtstreeks, d.w.z. cat /proc/kmsg.

Nu, als je de vriendelijke proc handleiding leest, zal deze je streng waarschuwen om slechts één gebruiker (die gepriviligeerd moet zijn) tegelijk /proc/kmsg te laten lezen. Welke syslog implementatie je ook hebt, het zou dit moeten doen, en vermoedelijk werkt het met dmesg. Ik weet het niet, ik ben buiten mijn bereik hier, ik parafraseer gewoon de handleiding. Dus terwijl dit de “zorg dat het @#$%ing werkt” manier is, overweeg dan eerst de volgende methodes.

Man page approved: watch + dmesg

Op een Linux box die ik gebruik met systemd init*, wordt dmesg.log niet erg vaak weggeschreven, misschien wel helemaal niet? De beste manier die ik vond om de kernel log buffer continu te lezen is met watch. Zoiets als dit zou je op weg moeten helpen (pas aan hoeveel regels er in je terminal passen):

watch 'dmesg | tail -50'

watch + dmesg + daemon + tail -f

Een meer ingewikkelde oplossing zou watch kunnen gebruiken om dmesg uitvoer naar een bestand te schrijven, dat je dan zou kunnen tail -f. U zou dit waarschijnlijk als een daemon willen draaien. Een echte daemon zou ook logs gzippen en roteren. De volgende bash code is niet getest, werkt niet, en is alleen bedoeld om een idee te geven. Het antwoord van @Brooks Moses heeft een werkende versie .

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

* raaklijn, want dit is een vraag over een apple desktop os: als systemd er is, doe dan geen moeite met dmesg; gebruik journalctl -xf (misschien met -n 100 om ook de vorige 100 regels te tonen)

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

Op Linux, sinds kernel kernel 3.5.0 kunt u gebruiken:

dmesg -w

Ook op systemen met systemd kun je gebruiken:

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

Hier is een variant op djeikyb’s antwoord die echt getest is, en een paar bugs verhelpt.

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

De belangrijke truc is dat we dmesg -c doen, die de ringbuffer leegmaakt na het afdrukken – dus, elke keer drukken we alleen af wat nieuw is sinds de laatste keer.

Je moet root zijn om dat te doen, vandaar de sudo. Er is ook een bugfix; in plaats van te proberen om zowel de uitvoer naar een bestand te dumpen als naar staart te pijpen (wat niet werkt), lezen we gewoon uit het nieuw-geschreven bestand.

We zouden gewoon dmesg > /tmp/dmesg.log kunnen doen en het hele bestand elke iteratie overschrijven, maar dat is een hoop I/O en riskeert ook het verlies van het bestand als de computer midden in een overschrijf crasht.

Je zou ook iets soortgelijks kunnen doen dat meer lijkt op tail -f met een while lus die dmesg -c en sleep 1 voor altijd uitvoert (zie Ben Harris’s antwoord). Maar aangezien dit in feite de kernel berichtbuffer leegmaakt terwijl hij draait, wil je misschien ook dingen naar een logbestand leiden voor het geval je ze later wilt hebben.

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

Ik deed dit voordat ik deze post zag:

#!/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 zijn wat ideeën voor beperkte omgevingen

Omgevingen zoals embedded of pre-boot, waar watch, tail, cat, dd en andere commando’s misschien niet beschikbaar zijn, hebben misschien andere gymnastiek nodig.

Dit is wat sommige lichtgewicht Linux distributies doen:

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

Het laat de while loop (met &) op de achtergrond terwijl je de gegenereerde output tailt.

Als je niet naar /tmp kunt schrijven:

mount -t tmpfs - /tmp 

# or 
mount -t ramfs - /tmp 

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

Als je geen tail hebt, kun je

cat /tmp/dmesg.log

# or 
dd if=/tmp/dmesg.log 

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

Of je zit misschien in een busybox omgeving waar dmesg niet gelinkt is, dan kun je gewoon:

busybox dmesg -c

Misschien moet je ook

busybox sleep

in plaats van sleep

Als je geen sleep hebt:

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

Als je geen “dmesg” hebt:

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

Dit werkt alleen als er niets anders van hier aan het lezen is. U zou ook een /dev/kmsg kunnen hebben.

Bonustip:

Als je niet weet wat je hebt, en je hebt geen “ls”, dan gewoon:

busybox ls

# or simply:

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

Je zou kunnen doen:

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

Ik gebruik deze alias in /root/.bashrc;

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

die dmesg volgt en de regels aanpast voor de terminal waarin hij wordt aangeroepen.

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

Onder de huidige Ubuntu (ik gebruik 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

( het sudo commando heeft sudo privilege nodig )

Probeer ook een andere zoals: 6<<( dmesg; sudo cat /proc/kmsg) cat /dev/fd/6

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

Ik gebruikte deze code om te zoeken naar een speciale kernel gebeurtenis en stuurde het een “callback” proces:

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

Dit kan handig zijn:

dmesg | tail -f -

pijpt de uitvoer van dmesg door tail en gebruikt de - operator als een snelkoppeling naar standaarduitvoer.