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

Czy jest możliwe `tail -f` na wyjściu `dmesg`?

Chcę zrobić coś w stylu

dmesg | tail -f

ale to nie działa:

Używam Mac OS X v10.6.7 (Snow Leopard). Robiąc to, tail wyjdzie, zamiast monitorować wyjście.

Zastanawiam się, czy istnieje sposób na zrobienie tego, lub równoważne polecenie.

P.S., nie sądzę, że pętla while będzie wystarczająco dobrym pomysłem.

Odpowiedzi (11)

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

Prawdopodobnie szukasz jakiejś kombinacji wiadomości z różnych plików dziennika. Spróbuj:

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

…aby uzyskać całkiem dobry przegląd systemu. Jeśli chcesz więcej lub mniej, sprawdź, w którym pliku dziennika znajdują się komunikaty, które chcesz zobaczyć.

Rozejrzyj się również za użyciem multitail do filtrowania wielu plików dziennika jednocześnie.

Edit: To nie było bardzo istotne, kiedy odpowiedziałem na to pytanie, ale ponieważ ta strona dostaje dużo wejść, pomyślałem, że warto wspomnieć, że nowsze systemy z systememd mają to.

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

Just make it @#$%ing work

  1. Chcesz drukować wyjście dmesg, ciągle, natychmiast
  2. Dmesg drukuje bufor pierścieniowy jądra (patrz man dmesg)
  3. Bufor pierścieniowy jądra jest specjalnym plikiem proc, /proc/kmsg (patrz man proc)
  4. Odczytaj /proc/kmsg bezpośrednio, tzn. cat /proc/kmsg.

Teraz, jeśli przeczytasz przyjazny podręcznik proc, ostrzeże cię on surowo, aby pozwolić tylko jednemu użytkownikowi (który musi być uprzywilejowany) czytać /proc/kmsg na raz. Jakakolwiek implementacja sysloga, którą masz, powinna to robić i przypuszczalnie działa z dmesg. I dunno, jestem poza moją ligą tutaj, po prostu parafrazując podręcznik. Więc podczas gdy jest to sposób “po prostu spraw, aby to @#$%ing działało”, rozważ najpierw kilka następnych metod.

Man page approved: watch + dmesg

Na jednym pudełku linuksa, którego używam z systemd init, dmesg.log nie jest zapisywany zbyt często, być może wcale? Najlepszym sposobem, jaki znalazłem na ciągłe czytanie bufora logu jądra jest użycie watch. Coś takiego powinno dać ci początek (dostosuj się do tego, ile linii zmieści się w twoim terminalu):

watch 'dmesg | tail -50'

watch + dmesg + daemon + tail -f

Bardziej zagmatwane rozwiązanie może używać watch do zapisywania wyjścia dmesg do pliku, który następnie możesz tail -f. Prawdopodobnie chciałbyś, żeby to działało jako demon. Właściwy demon powinien również gzipować i obracać logi. Poniższy kod basha jest nieprzetestowany, niedziałający i ma na celu jedynie przekazanie idei. Odpowiedź @Brooks Moses ma wersja robocza .

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

* styczne, ponieważ jest to pytanie dotyczące systemu desktopowego jabłka: kiedy systemd jest w pobliżu, nie zawracaj sobie głowy dmesg; użyj journalctl -xf (może w/ -n 100 aby pokazać również poprzednie 100 linii)

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

Na Linuksie, od czasu jądra kernel 3.5.0 można używać:

dmesg -w

Również na systemach z systemd można użyć:

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

Oto wariant na odpowiedź djeikyb , który został faktycznie przetestowany i naprawia kilka błędów.

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

Ważną sztuczką jest to, że wykonujemy dmesg -c, który czyści bufor pierścieniowy po wydrukowaniu - w ten sposób za każdym razem drukujemy tylko to, co jest nowe od ostatniego razu.

Aby to zrobić, musisz być rootem, stąd sudo. Jest też poprawka błędu; zamiast próbować zarówno zrzucić wyjście do pliku, jak i przekazać je do taila (co nie działa), po prostu czytamy z nowo napisanego pliku.

Moglibyśmy zrobić po prostu dmesg > /tmp/dmesg.log i nadpisywać cały plik przy każdej iteracji, ale to dużo I/O, a także ryzykujemy utratę pliku, jeśli komputer zawiesi się w środku nadpisywania.

Mógłbyś również zrobić coś podobnego, co jest bardziej zbliżone do tail -f z pętlą while, która wykonuje dmesg -c i sleep 1 na zawsze (zobacz odpowiedź Bena Harrisa). Jednakże, ponieważ jest to faktycznie czyszczenie bufora wiadomości jądra podczas działania, możesz również chcieć przesłać rzeczy do pliku dziennika na wypadek, gdybyś chciał je później.

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

Zrobiłem to zanim zobaczyłem ten 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

Oto kilka pomysłów dla ograniczonych środowisk

Środowiska takie jak embedded lub pre-boot, gdzie watch, tail, cat, dd i inne komendy mogą nie być dostępne, mogą wymagać innej gimnastyki.

Oto co robią niektóre lekkie dystrybucje Linuksa:

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

Tłoczy pętlę while (z &) podczas ogonowania wygenerowanego wyjścia.

Jeśli nie możesz pisać do /tmp:

mount -t tmpfs - /tmp 

# or 
mount -t ramfs - /tmp 

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

Jeśli nie masz taila, możesz

cat /tmp/dmesg.log

# or 
dd if=/tmp/dmesg.log 

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

Albo możesz być w środowisku busybox, które nie ma podlinkowanego dmesg, wtedy po prostu:

busybox dmesg -c

Możesz też potrzebować

busybox sleep

zamiast sleep

Jeśli nie masz sleep:

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

Jeśli nie masz “dmesg”:

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

To działa tylko wtedy, gdy nic innego nie czyta stąd. Możesz mieć również /dev/kmsg.

Bonusowa wskazówka:

Jeśli nie wiesz co masz, i nie masz “ls”, po prostu:

busybox ls

# or simply:

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

Możesz być w stanie zrobić:

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

Używam tego aliasu w /root/.bashrc;

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

który podąża za dmesg i dostosowuje linie do terminala, w którym jest wywoływany.

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

Pod aktualnym Ubuntu (używam 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

( polecenie sudo wymaga uprawnień sudo )

Proszę również spróbować innego jak: 6( dmesg; sudo cat /proc/kmsg) cat /dev/fd/6

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

Użyłem tego kodu do szukania specjalnego zdarzenia jądra i przekazania go do procesu “callback”:

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

To może być użyteczne:

dmesg | tail -f -

pipes the output of dmesg through tail using the - operator as a shortcut to standard output.