Wyjście polecenia „obserwuj” jako listę

27

Chcę wykonać proste obliczenie liczby linii na minutę dodanych do pliku dziennika.

Chcę również przechowywać liczbę dla każdej sekundy.

Potrzebuję danych wyjściowych następującego polecenia jako listy, która będzie aktualizowana co sekundę:

watch -n1 'wc -l my.log'

Jak wypisać „aktualizację” polecenia „obserwuj” jako listę?

JohnJohnGa
źródło

Odpowiedzi:

24

Możesz użyć -tprzełącznika, watchktóry powoduje, że nie drukuje nagłówka. Jednak to nadal wyczyści ekran, więc możesz być lepszy dzięki prostej pętli powłoki:

while sleep 1; do
    wc -l my.log
done

Jedną z zalet jest to, że można łatwo dodawać inne polecenia (np. date) I / lub przesyłać dane wyjściowe w sedcelu ponownego sformatowania. Nawiasem mówiąc, jeśli zamienisz sleep 1się wcw pętli, automatycznie zakończy się w przypadku błędów.

Peter
źródło
Należy jednak pamiętać, że nie będzie to robić dokładnie co sekundę (w przypadku zsh lub ksh93 można dostosować czas snu, aby uwzględnić dryf związany z uruchamianiem poleceń w pętli)
Stéphane Chazelas,
2
@StephaneChazelas też tego nie zrobi wait- po prostu spróbuj watch -n 1 "sleep 5".
Peter
Rzeczywiście (sprawdziłem implementacje procps i busybox). Myślałem, że to jedyna rzecz, która watchbyła przydatna, ale to nie daje nawet tego, więc twoje rozwiązanie jest tak dobre, jak rozwiązanie oparte na zegarku, ale żadne z nich nie odpowiada z dużą dokładnością na pytanie „szybkość, z jaką plik dziennika rośnie” .
Stéphane Chazelas,
Cóż, jeśli ostatecznym celem są linie na minutę , to próbkowanie go raz na 10 sekund jest więcej niż wystarczające imho - więc narzut nie jest tak straszny (chyba że plik oczywiście stanie się naprawdę duży). I faktycznie z poziomu pętli można wydrukować informacje o taktowaniu (nawet zarówno przed, jak i po zakończeniu polecenia, jeśli to konieczne), a następnie dokładność może wzrosnąć (rzędy wielkości) nawet dla większych plików.
peterph
1
@peterph watchma -popcję, która zrobi to dobrze, jeśli to w ogóle możliwe (oczywiście, nie możesz wykonać polecenia, które zajmuje 5 sekund co 1 sekundę, jeśli nie masz pozwolenia na wiele jednoczesnych). Wiem, napisałem to :-P
derobert
8

Stare pytanie, ale właśnie znalazłem bardzo łatwą odpowiedź:

watch -n1 'wc -l my.log | tee -a statistics.log'

Spowoduje to wykonanie wckażdej sekundy, dodanie danych wyjściowych do pliku Statistics.log, a także wyświetlenie go na ekranie.
Otrzymasz plik wypełniony liczbami reprezentującymi kolejną liczbę wierszy my.log.

Orabin
źródło
Pamiętaj, że to polecenie watch "($MYCMD | tee -a $MYLOG)"nie jest watch "($MYCMD)" | tee -a $MYLOG. Jeśli pomyliłeś się tak jak ja, wynik będzie bardzo, bardzo mylący. Inną rzeczą wartą odnotowania jest to, że to polecenie domyślnie nie dodaje znacznika czasu wykonania każdego polecenia, więc odpowiedź z pętlą może nadal działać lepiej.
sfledgling
3

Co powiesz na

tail -f file.log | pv -rl > /dev/null
Stéphane Chazelas
źródło
3

Spróbuj wykonać następujące czynności:

watch -n1 'wc -l my.log >> statistics.log'
Andy
źródło
1

Natknąłem się na to pytanie, gdy próbowałem uzyskać lepsze / zarejestrowane dane wyjściowe du -sh $data_path. Użyłem wzorca „while while, do sleep” znalezionego tutaj, ale użyłem złożonego AWK, aby uzyskać pożądany wynik.

while du -sh $data_path; do sleep 1; done | awk '
$1 != size {
    size=$1;
    path=$2;
    time=systime();
    seconds=time-prevtime;
    if(seconds < 1000000000){
        seconds=seconds" seconds"
    }else{
        seconds=""
    }
    print size, path, strftime("%m/%d/%Y@%H:%M:%S", time), seconds; 
    prevtime=time
}'

Zrobiłem to jako oneliner i dlatego są średniki. Ale żeby było czytelne, wyrwałem to. Dane wyjściowe wyglądają następująco:

502G /var/lib/cassandra/dump/ 05/22/2018@04:46:17
503G /var/lib/cassandra/dump/ 05/22/2018@04:46:59 42 seconds
504G /var/lib/cassandra/dump/ 05/22/2018@04:47:57 58 seconds
505G /var/lib/cassandra/dump/ 05/22/2018@04:48:55 58 seconds
506G /var/lib/cassandra/dump/ 05/22/2018@04:49:53 58 seconds
507G /var/lib/cassandra/dump/ 05/22/2018@04:50:50 57 seconds
508G /var/lib/cassandra/dump/ 05/22/2018@04:51:46 56 seconds
509G /var/lib/cassandra/dump/ 05/22/2018@04:52:44 58 seconds
510G /var/lib/cassandra/dump/ 05/22/2018@04:53:41 57 seconds
Bruno Bronosky
źródło
0

Możesz stworzyć skrypt, który zrobi to za Ciebie. Zadzwoniłem do mojego keep(jak, rób to dalej) i umieściłem go na binścieżce.

To jest mój skrypt:

#!/bin/bash
echo "Repeating command $* every second"
while sleep 1; do
    "$@"
done
Alexandre Santos
źródło
1
Powinieneś użyć "$@"do wykonania polecenia (argumentów) zamiast bez cudzysłowu $*. W ten sposób powłoka będzie przechowywać argumenty cytowane itp., Tak jak użytkownik by ich oczekiwał. FTFY.
roaima,