Mam dziennik serwera, który wyświetla określony wiersz tekstu w pliku dziennika, gdy serwer jest uruchomiony. Chcę wykonać polecenie po uruchomieniu serwera, a zatem wykonaj następujące czynności:
tail -f /path/to/serverLog | grep "server is up" ...(now, e.g., wget on server)?
Jak najlepiej to zrobić?
tail -F
do obsługi rotacji kłód - tzn.my.log
zapełnia się i przechodzi do,my.log.1
a proces tworzy nowymy.log
Odpowiedzi:
Prostym sposobem byłoby awk.
I tak, oba są prawdziwymi komunikatami z dziennika jądra. Perl może być nieco bardziej elegancki w użyciu do tego i może również zastąpić potrzebę ogona. Jeśli używasz perla, będzie on wyglądał mniej więcej tak:
źródło
awk
być krótki i łatwy do zrobienia w locie w jednej linii. Jeśli jednak polecenie, które chcę uruchomić, zawiera cudzysłowy, może to być nieco kłopotliwe, czy istnieje alternatywa, być może użycie potoków i poleceń złożonych, które również pozwalają na krótkie rozwiązanie jednoliniowe, ale nie wymagają przekazania wynikowego polecenia jako sznurek?system()
polecenia.tail -f /path/to/serverLog | grep "server is up" | head -1 && do_some_command
tail -n 0 -f /path/to/serverLog
odczytanie ostatnich 0 wierszy pliku, a następnie poczekanie na wydrukowanie kolejnych wierszy.Jeśli szukasz tylko jednej możliwości i chcesz pozostać w powłoce, zamiast używać
awk
lubperl
, możesz zrobić coś takiego:... który będzie działał za
my_command
każdym razem, gdy w pliku dziennika pojawi się „ serwer jest uruchomiony ”. Aby uzyskać wiele możliwości, możesz upuścićgrep
i zamiast tego użyć znakucase
wewnątrzwhile
.Stolica
-F
każetail
uważać, aby plik dziennika został obrócony; tzn. jeśli nazwa bieżącego pliku zostanie zmieniona, a inny plik o tej samej nazwietail
zostanie zastąpiony , przełączy się na nowy plik.--line-buffered
Opcja nakazujegrep
opróżnić swój bufor po każdej linii; w przeciwnym raziemy_command
może nie zostać osiągnięte w odpowiednim czasie (zakładając, że kłody mają linie o rozsądnych rozmiarach).źródło
--line-buffered
opcjęgrep
, lub w inny sposób upewnić się, że opróżnia swój wynik między wierszami: w przeciwnym razie po prostu zawiesza się imy_command
nigdy nie jest osiągany. Jeśli woliszack
, ma--flush
flagę; jeśli woliszag
, spróbuj owinąćstdbuf
. stackoverflow.com/questions/28982518/…do exit ;
. Wydawało się, że działa dobrze, ale ogon nigdy się nie skończył, a nasz skrypt nigdy nie przeszedł do następnego wiersza. Czy jest jakiś sposób, aby zatrzymać ogon wdo
sekcji?Wydaje się, że na to pytanie już udzielono odpowiedzi, ale myślę, że istnieje lepsze rozwiązanie.
Zamiast
tail | whatever
tego myślę, że tak naprawdę chceszswatch
. Swatch to program zaprojektowany specjalnie do robienia tego, o co prosisz, oglądania pliku dziennika i wykonywania działań opartych na wierszach dziennika. Korzystanie z niegotail|foo
będzie wymagało aktywnego terminalu, aby to zrobić. Z drugiej strony Swatch działa jako demon i zawsze będzie obserwował twoje dzienniki. Swatch jest dostępny we wszystkich dystrybucjach Linuksa,Zachęcam do wypróbowania tego. Chociaż możesz wbić gwóźdź tylną stroną śrubokręta, nie oznacza to, że powinieneś.
Najlepszy 30-sekundowy samouczek na temat próbki, jaki udało mi się znaleźć, znajduje się tutaj: http://www.campin.net/newlogcheck.html
źródło
Dziwne, że nikt nie wspomniał o
multitail
narzędziu, które ma tę funkcjonalność po wyjęciu z pudełka. Jeden z przykładów użycia:Zobacz także kolejne przykłady z
multitail
użytkowania.źródło
bash mógł wykonać tę pracę sam
Zobaczmy, jak proste i czytelne może być:
Chociaż nie używasz bash
regex
, może to być bardzo szybkie!Ale bash + sed to bardzo wydajny i interesujący tandem
Ale w przypadku serwera o wysokim obciążeniu i jak mi się podoba,
sed
ponieważ jest bardzo szybki i bardzo skalowalny, często używam tego:źródło
Tak też zacząłem to robić, ale stałem się o wiele bardziej wyrafinowany. Kilka rzeczy, którymi należy się martwić:
Używam czegoś takiego:
Działa, trzymając
tail
otwarte, dopóki${RELEASE}
plik nie zawiera danych.Gdy to się
grep
powiedzie:${RELEASE}
których będzie${wait_pid}
proces dotail
Uwaga:
sed
Mogą być bardziej wyrafinowane, aby faktycznie określić liczbę linii, któretail
zostaną wygenerowane podczas uruchamiania i usuń tę liczbę. Ale ogólnie jest 10.źródło