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

¿Es posible "cola -f" la salida de "dmesg"?

Quiero hacer algo como

dmesg | tail -f

pero no funciona:

Utilizo Mac OS X v10.6.7 (Snow Leopard). Al hacer eso, tail saldrá, en lugar de controlar la salida.

Me pregunto si hay una forma de hacerlo, o un comando equivalente.

P.D., no creo que un bucle while sea una buena idea.

Respuestas (11)

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

Probablemente esté buscando alguna combinación de mensajes de varios archivos de registro. Pruebe:

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

…para obtener una buena visión general del sistema. Si quieres más o menos que eso, investiga en qué archivo de registro se están colocando los mensajes que quieres ver.

También busque el uso de multitail para archivar y codificar por colores y filtrar múltiples archivos de registro a la vez.

Edición: Esto no era muy relevante cuando respondí a esto, pero como esta página recibe muchas visitas pensé que valía la pena mencionar que los sistemas más nuevos que ejecutan systemd tienen esto.

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

Sólo haz que @#$% funcione

  1. Quieres imprimir la salida de dmesg, constantemente, inmediatamente
  2. Dmesg está imprimiendo el ring buffer del kernel (ver man dmesg)
  3. El ring buffer del kernel es un archivo proc especial, /proc/kmsg (ver man proc)
  4. Lee directamente /proc/kmsg, es decir, cat /proc/kmsg.

Ahora, si lees el amistoso manual de proc, te advertirá severamente que sólo dejes que un usuario (que debe tener privilegios) lea /proc/kmsg a la vez. Cualquiera que sea la implementación de syslog que tengas debe hacer esto, y presumiblemente funciona con dmesg. No sé, estoy fuera de mi liga aquí, sólo parafraseando el manual. Así que mientras que esta es la forma de “simplemente hacer que @#$% funcione”, considere el siguiente par de métodos primero.

Página de manual aprobada: watch + dmesg

En una caja de linux que uso con systemd init*, dmesg.log no se escribe muy a menudo, ¿quizás nada? La mejor manera que encontré para leer el buffer de registro del kernel continuamente es con watch. Algo como esto debería servirle para empezar (ajuste para cuántas líneas caben en su terminal):

watch 'dmesg | tail -50'

watch + dmesg + daemon + tail -f

Una solución más complicada podría usar watch para escribir la salida de dmesg en un archivo, que luego podría tail -f. Probablemente querrás que esto se ejecute como un demonio. Un demonio adecuado también comprimiría y rotaría los registros. El siguiente código bash no está probado, no funciona, y sólo pretende transmitir una idea. La respuesta de @Brooks Moses tiene una versión funcional .

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

\N - tangente, porque esta es una pregunta sobre un sistema operativo de escritorio de apple: cuando systemd está cerca, no te molestes con dmesg; usa journalctl -xf (tal vez con -n 100 para mostrar también las 100 líneas anteriores)

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

En Linux, desde el kernel 3.5.0 se puede utilizar

dmesg -w

También en sistemas con systemd se puede usar:

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

Aquí hay una variante de la respuesta de djeikyb que está realmente probada, y corrige un par de errores.

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

El truco importante es que estamos haciendo dmesg -c, que limpia el buffer del anillo después de imprimirse – así, cada vez que se imprime sólo se imprime lo que es nuevo desde la última vez.

Necesitarás ser root para hacerlo, por eso el sudo. También hay una corrección de errores; en lugar de tratar de volcar la salida a un archivo y canalizarla a tail (lo que no funciona), sólo estamos leyendo desde el archivo recién escrito.

Podríamos hacer sólo dmesg > /tmp/dmesg.log y sobrescribir todo el archivo en cada iteración, pero eso es mucha E/S y también se corre el riesgo de perder el archivo si el ordenador se bloquea en medio de una sobrescritura.

También podrías hacer algo similar que se parezca más a tail -f con un bucle while que ejecute dmesg -c y sleep 1 para siempre (ver la respuesta de Ben Harris). Sin embargo, ya que esto está limpiando el búfer de mensajes del kernel mientras se está ejecutando, es posible que también desee canalizar las cosas en un archivo de registro en caso de que las quiera más tarde.

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

Lo hice antes de ver este 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

Aquí hay algunas ideas para entornos limitados

Entornos como los embebidos o de pre-arranque, donde watch, tail, cat, dd y otros comandos pueden no estar disponibles, pueden necesitar una gimnasia diferente.

Esto es lo que hacen algunas distribuciones ligeras de Linux:

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

Pasa a un segundo plano el bucle while (con &) mientras hace cola en la salida generada.

Si no puede escribir en /tmp:

mount -t tmpfs - /tmp 

# or 
mount -t ramfs - /tmp 

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

Si no tienes tail, puedes

cat /tmp/dmesg.log

# or 
dd if=/tmp/dmesg.log 

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

O puedes estar en un entorno busybox que no tiene dmesg enlazado, entonces simplemente:

busybox dmesg -c

También podrías necesitar

busybox sleep

en lugar de sleep

Si no tienes sleep:

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

Si no tienes “dmesg”:

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

Esto sólo funciona si no hay nada más leyendo desde aquí. También puede tener un /dev/kmsg.

Consejo extra:

Si no sabes lo que tienes, y no tienes “ls”, simplemente:

busybox ls

# or simply:

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

Podrías hacer:

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

Yo uso este alias en /root/.bashrc;

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

que sigue a dmesg y ajusta las líneas para cualquier terminal en la que se llame.

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

Bajo el actual Ubuntu (estoy 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

( el comando sudo necesita el privilegio sudo )

Por favor, pruebe también otro como: 6< <( dmesg; sudo cat /proc/kmsg) cat /dev/fd/6

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

Usé este código para buscar un evento especial del kernel y lo canalicé a un proceso de “callback”:

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

Esto puede ser útil:

dmesg | tail -f -

canaliza la salida de dmesg a través de tail usando el operador - como un atajo a la salida estándar.