Tło:
Piszę skrypt testowy dla oprogramowania biologii obliczeniowej. Oprogramowanie, które testuję, może trwać kilka dni, a nawet tygodni, więc ma wbudowane funkcje odzyskiwania w przypadku awarii systemu lub awarii zasilania.
Próbuję wymyślić, jak przetestować system odzyskiwania. W szczególności nie mogę znaleźć sposobu na „zawieszenie” programu w kontrolowany sposób. Zastanawiałem się nad czasem, aby rozkaz SIGKILL działał po pewnym czasie. Prawdopodobnie nie jest to idealne rozwiązanie, ponieważ nie gwarantuje się, że przypadek testowy będzie działał z tą samą prędkością za każdym razem (działa we wspólnym środowisku), więc porównanie dzienników z pożądanymi danymi wyjściowymi byłoby trudne.
To oprogramowanie drukuje wiersz dla każdej sekcji analizy, którą wykonuje.
Pytanie:
Zastanawiałem się, czy istnieje dobry / elegancki sposób (w skrypcie powłoki), aby przechwycić dane wyjściowe z programu, a następnie zabić program, gdy dany wiersz / liczba wierszy jest wysyłana przez program?
Odpowiedzi:
Skrypt otoki taki jak ten jest standardowym podejściem. Skrypt uruchamia program w tle, a następnie zapętla, sprawdzając plik dziennika co minutę pod kątem jakiegoś ciągu. Jeśli ciąg zostanie znaleziony, program w tle zostanie zabity i skrypt zostanie zamknięty.
źródło
Jeśli twój program zakończy działanie na SIGPIPE (co jest domyślną akcją), powinno wystarczyć przekierowanie wyjścia do czytnika, który wyjdzie po przeczytaniu tego wiersza.
Może to być tak proste jak
Jeśli chcesz ukryć domyślne wyjście, użyj
Podobnie, jeśli chce się zatrzymać po określonej liczbie linii, można użyć głowy zamiast sed, np
Dokładny czas, w którym nastąpi zabójstwo , zależy od buforowania zachowania terminala, jak sugeruje stardt w komentarzach.
źródło
sed
zakończeniu. OP mówi: „To oprogramowanie drukuje wiersz dla każdej sekcji analizy, którą wykonuje”. Może to oznaczać, że program ukończy jedną dodatkową sekcję! Dowód koncepcji:{ echo 1; sleep 3; >&2 echo peekaboo; sleep 3; echo 2; } | sed -e '/1/q'
. Zobacz tę odpowiedź . Możliwe obejście:( program & ) | sed -e '/Suitable text from the line/q'; killall program
. Uczyń swoją odpowiedź świadomą wadę, a ja odwołam moje zdanie.Alternatywą dla odpowiedzi dmckee jest także
grep
polecenie z-m
opcją (patrz np. Ta strona podręcznika ):zatrzymać, gdy zostanie znaleziony 1 wiersz pasujący do tekstu lub
czekać na 10 wierszy, które nie pasują do podanego tekstu.
źródło
Możesz użyć
expect(1)
do obejrzenia standardowego programu, a następnie wykonać predefiniowane działanie na niektórych wzorcach.Lub linijka do osadzenia w innym skrypcie:
Pamiętaj, że
expect
polecenie nie jest domyślnie dostarczane z każdym systemem operacyjnym. Może być konieczne jego zainstalowanie.źródło
set timeout -1
o ustawieniu limitu czasu nieokreślonego, w przeciwnym razie wszystko zamknie się poniżejexpect
domyślnego limitu 10 sekund.Możesz użyć instrukcji „while”:
Musisz przesłać dane wyjściowe swojego oprogramowania (lub jego dzienników), a następnie, dla każdej nowej linii, wykonać test warunkowy, a następnie uruchomić polecenie kill -KILL. Na przykład (testowałem z plikiem / var / log / messages jako plikiem dziennika):
Lub bezpośrednio z oprogramowaniem:
Musisz zastąpić ścieżkę dziennika / nazwę aplikacji, pasujący wiersz i PID do zabicia (możesz także użyć killall).
Powodzenia w oprogramowaniu,
Hugo,
źródło