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

È possibile fare il `tail -f` dell'output di `dmesg`?

Voglio fare qualcosa come

dmesg | tail -f

ma non funziona:

Uso Mac OS X v10.6.7 (Snow Leopard). Facendo così, tail uscirà, invece di monitorare l'uscita.

Mi chiedo se c'è un modo per farlo, o un comando equivalente.

P.S., non credo che un ciclo while sia una buona idea.

Risposte (11)

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

Probabilmente stai cercando una combinazione di messaggi da vari file di log. Provate:

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

…per avere una panoramica abbastanza buona del sistema. Se vuoi più o meno di questo, cerca in quale file di log i messaggi che vuoi vedere vengono inseriti.

Guarda anche come usare multitail per archiviare e colorare e filtrare più file di log in una volta sola.

Modifica: Questo non era molto rilevante quando ho risposto, ma dato che questa pagina riceve molte visite, ho pensato che valesse la pena menzionare che i sistemi più recenti con systemd hanno questo.

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

Just make it @#$%% work

  1. Vuoi stampare l'output di dmesg, costantemente, immediatamente
  2. Dmesg sta stampando il ring buffer del kernel (vedi man dmesg)
  3. Il ring buffer del kernel è un file proc speciale, /proc/kmsg (vedi man proc)
  4. Leggi direttamente /proc/kmsg, cioè cat /proc/kmsg.

Ora, se leggete l'amichevole manuale di proc, vi avvertirà severamente di lasciare che solo un utente (che deve essere privilegiato) legga /proc/kmsg alla volta. Qualsiasi implementazione syslog abbiate dovrebbe fare questo, e presumibilmente funziona con dmesg. Non so, sono fuori dalla mia portata qui, sto solo parafrasando il manuale. Quindi, mentre questo è il modo “fallo solo funzionare @#$%%”, considerate prima i prossimi due metodi.

Pagina uomo approvata: watch + dmesg

Su una scatola linux che uso con systemd init*, dmesg.log non viene scritto molto spesso, forse per niente? Il modo migliore che ho trovato per leggere continuamente il buffer di log del kernel è con watch. Qualcosa come questo dovrebbe farvi iniziare (aggiustate per quante linee ci stanno nel vostro terminale):

watch 'dmesg | tail -50'

watch + dmesg + daemon + tail -f

Una soluzione più contorta potrebbe usare watch per scrivere l'output di dmesg su file, che potreste poi tail -f. Probabilmente vorrete che questo venga eseguito come demone. Un demone adeguato dovrebbe anche gzippare e ruotare i log. Il seguente codice bash non è testato, non funziona, ed è inteso solo a trasmettere un'idea. La risposta di @Brooks Moses ha una versione funzionante .

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

* tangente, perché questa è una domanda su un sistema operativo desktop apple: quando c'è systemd, non preoccupatevi di dmesg; usate journalctl -xf (forse con -n 100 per mostrare anche le 100 linee precedenti)

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

Su Linux, dal kernel 3.5.0 si può usare:

dmesg -w

Anche sui sistemi con systemd potete usare:

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

Ecco una variante sulla risposta di djeikyb che è effettivamente testata, e risolve un paio di bug.

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

Il trucco importante è che stiamo facendo dmesg -c, che cancella il ring buffer dopo aver stampato – così, ogni volta stiamo stampando solo ciò che è nuovo dall'ultima volta.

Dovrai essere root per farlo, quindi lo sudo. C'è anche un bugfix; invece di provare sia a scaricare l'output in un file che a pipearlo in tail (che non funziona), stiamo solo leggendo dal file appena scritto.

Potremmo fare solo dmesg > /tmp/dmesg.log e sovrascrivere l'intero file ad ogni iterazione, ma questo è un sacco di I/O e rischia anche di perdere il file se il computer va in crash nel mezzo di una sovrascrittura.

Si potrebbe anche fare qualcosa di simile che è più simile a tail -f con un ciclo while che esegue dmesg -c e sleep 1 per sempre (vedere la risposta di Ben Harris). Tuttavia, dal momento che questo sta effettivamente cancellando il buffer dei messaggi del kernel mentre è in esecuzione, si potrebbe anche voler convogliare le cose in un file di registro nel caso in cui le si voglia in seguito.

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

L'ho fatto prima di vedere questo post:

#!/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

Ecco alcune idee per ambienti limitati

Ambienti come quelli embedded o pre-boot, dove watch, tail, cat, dd e altri comandi potrebbero non essere disponibili, potrebbero richiedere una ginnastica diversa.

Questo è ciò che fanno alcune distribuzioni Linux leggere:

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

Sfondo il ciclo while (con &) mentre si pedina l'output generato.

Se non puoi scrivere su /tmp:

mount -t tmpfs - /tmp 

# or 
mount -t ramfs - /tmp 

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

Se non avete tail, potete

cat /tmp/dmesg.log

# or 
dd if=/tmp/dmesg.log 

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

Oppure potreste essere in un ambiente busybox che non ha dmesg collegato, allora solo:

busybox dmesg -c

Potresti anche aver bisogno di

busybox sleep

invece di sleep

Se non hai sleep:

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

Se non hai “dmesg”:

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

Questo funziona solo se nient'altro sta leggendo da qui. Potresti anche avere un /dev/kmsg.

Bonus tip:

Se non sapete cosa avete, e non avete “ls”, semplicemente:

busybox ls

# or simply:

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

Potreste fare:

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

Io uso questo alias in /root/.bashrc;

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

che segue dmesg e regola le linee per qualsiasi terminale in cui è chiamato.

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

Sotto l'attuale Ubuntu (sto usando 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

( il comando sudo ha bisogno dei privilegi sudo)

Per favore provate anche un altro come: 6< <( dmesg; sudo cat /proc/kmsg) cat /dev/fd/6

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

Ho usato questo codice per cercare un evento speciale del kernel e l'ho collegato a un processo di “callback”:

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

Questo potrebbe essere utile:

dmesg | tail -f -

fa passare l'output di dmesg attraverso tail usando l'operatore - come scorciatoia per lo standard output.