Szukam sposobu, aby programowo obserwować wyjście polecenia, dopóki nie zostanie zaobserwowany określony ciąg, a następnie wyjść. Jest to bardzo podobne do tego pytania, ale zamiast ogoniać plik, chcę „ogonić” polecenie.
Coś jak:
obejrzyj -n1 my_cmd | grep -m 1 „Ciąg szukam”
(Ale to nie działa dla mnie.)
AKTUALIZACJA: Muszę wyjaśnić, że „my_cmd” nie wysyła w sposób ciągły tekstu, ale musi być wielokrotnie wywoływany, dopóki nie zostanie znaleziony ciąg znaków (dlatego pomyślałem o poleceniu „obserwuj”). Pod tym względem „my_cmd” jest podobny do wielu innych poleceń unixowych, takich jak: ps, ls, lsof, last itp.
tail -f
jest wyjście programu tak samo jak pliku ... Czy się mylę?Odpowiedzi:
Użyj pętli:
Zamiast tego
:
możesz użyćsleep 1
(lub 0.2), aby ułatwić procesor.Pętla działa, dopóki grep nie znajdzie łańcucha w danych wyjściowych polecenia.
-m 1
oznacza „wystarczy jedno dopasowanie”, tzn. grep przestaje wyszukiwać po znalezieniu pierwszego dopasowania.Możesz także użyć polecenia,
grep -q
które kończy pracę po znalezieniu pierwszego dopasowania, ale bez drukowania pasującej linii.źródło
grep -q
co jest inną opcją. grep kończy pracę po znalezieniu ciągu.!
neguje kod wyjścia potoku poleceńgrep -m 1
kończy się po znalezieniu ciąguwatch -e
zwraca, jeśli wystąpił jakikolwiek błądAle można to poprawić, aby wyświetlać tę dopasowaną linię, która jest wyrzucana do tej pory.
źródło
watch
polecenie (CentOS) nie ma-e
flagi (co nie powinno tak naprawdę mieć znaczenia). Co ważniejsze, po znalezieniu łańcucha zegarek nadal działa i nie wychodzi. Wygląda na to, że kiedygrep -m
wychodzi, wychodzi tylko z zabójstwmy_cmd
, ale niewatch
.tee
do tego zatrudnić , ale wprowadza to wprowadzającą w błąd nową linię, nie wiem jak teraz obejść:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
watch
posłusznie przestaje oglądać, gdy łańcuch zostanie znaleziony, ale tak naprawdę nie wychodzi, dopóki nie naciśniesz klawisza. Tak blisko.Dla tych, którzy mają program, który ciągle pisze na standardowe wyjście, wszystko, co musisz zrobić, to potokować go grep za pomocą opcji „single match”. Gdy grep znajdzie pasujący ciąg, zakończy działanie, co zamyka standardowe wyjście procesu, który jest przesyłany do grep. To zdarzenie powinno naturalnie spowodować, że program z wdziękiem zakończy działanie , o ile proces zacznie ponownie pisać .
Stanie się tak, że proces otrzyma SIGPIPE, gdy spróbuje napisać do zamkniętego wyjścia po wyjściu z grep. Oto przykład z pingiem, który w innym przypadku działałby w nieskończoność:
To polecenie pasuje do pierwszego udanego „ponga”, a następnie kończy pracę przy następnej
ping
próbie zapisu na standardowe wyjście.Jednak,
Nie zawsze jest zagwarantowane, że proces ponownie zapisze na standardowym wyjściu i dlatego może nie spowodować podniesienia SIGPIPE (np. Może się to zdarzyć podczas modyfikowania pliku dziennika). Najlepsze rozwiązanie, jakie udało mi się wymyślić w tym scenariuszu, polega na zapisaniu do pliku; prosimy o komentarz, jeśli uważasz, że możesz poprawić:
Podział tego:
tail -f log_file & echo $! > pid
- dołącza plik do pliku, dołącza proces do tła i zapisuje PID ($!
) w pliku. Zamiast tego próbowałem wyeksportować PID do zmiennej, ale wygląda na to, że pomiędzy tym miejscem a tym, kiedy PID zostanie ponownie użyty, istnieje warunek wyścigu.{ ... ;}
- zgrupuj te polecenia razem, abyśmy mogli przesyłać dane wyjściowe do grep, zachowując bieżący kontekst (pomaga przy zapisywaniu i ponownym użyciu zmiennych, ale nie był w stanie uruchomić tej części)|
- przesuń rurkę z wejścia standardowego do wejścia z prawej stronygrep -m1 "find_me"
- znajdź docelowy ciąg&& kill -9 $(cat pid)
- force kill (SIGKILL)tail
proces pogrep
wyjściu, gdy znajdzie pasujący ciąg&& rm pid
- usuń utworzony przez nas plikźródło
Jeśli
tail
nie obsługuje+1f
składni, spróbujtail -f -n +1
. (-n +1
Mówi, że ma zacząć od początku;tail -f
domyślnie zaczyna się od ostatnich 10 wierszy wyniku).źródło
Dołącz wynik wywołania programu do pliku. Potem
tail -f
ten plik. W ten sposób powinno działać ... Mam nadzieję.Po ponownym uruchomieniu tego programu musisz usunąć plik lub dodać do niego bełkot, aby od razu nie pasował do tego, czego szukałeś.
źródło