Sprawdzanie, czy wyjście polecenia zawiera określony ciąg w skrypcie powłoki
117
Piszę skrypt powłoki i próbuję sprawdzić, czy dane wyjściowe polecenia zawierają określony ciąg. Myślę, że prawdopodobnie muszę użyć grep, ale nie jestem pewien jak. Czy ktoś wie?
Czy polecenie musi działać dalej po wygenerowaniu ciągu wyjściowego, którego szukasz, czy może zostać natychmiast zamknięte w tym czasie? (Twoje dwie odpowiedzi różnią się pod tym względem semantyką).
Ponadto grep 'string' &>/dev/nulljest niezgodny z POSIX i znacznie wolniejszy do wykonania (jeśli stringpojawia się wcześnie w długim strumieniu wyjściowym) niż grep -q string. [Zastrzeżenie polega na tym, że jeśli chcesz mieć pewność, somecommandże działa nawet po wyemitowaniu string, w takim przypadku użycie grep -q- poprzez zamknięcie standardowego wejścia i wyjście po pierwszym wystąpieniu string- może przynieść efekt przeciwny do zamierzonego]. (Re: "niezgodne z POSIX", &>to rozszerzenie - patrz pubs.opengroup.org/onlinepubs/009695399/utilities/ ... opisujące obsługę przekierowań narzuconych przez POSIX).
Charles Duffy,
Pomogłoby, gdyby zostało wyjaśnione, dlaczego to działa / co robi każdy parametr, aby zachęcić do pełnego zrozumienia składni
Jeśli przypadkiem chcesz tylko przetestować stały ciąg, dodać F i x opcje: grep -FxqF oznacza stałe (nie interpretować) i X na całej linii
Erdal G.
4
Dlaczego testowanie $?jest anty-wzorcem?
Witalij Zdanevich
1
@VitalyZdanevich Zakładam, ponieważ nie jest odporny na współbieżność.
Konrad Reiche
@VitalyZdanevich, na przykład, testowanie $?nie ustawia poprzednich poleceń jako „sprawdzonych” dla celów set -elub ERRpułapki, więc twój program może zakończyć się w przypadkach, gdy chcesz, aby po prostu powrócił później celowo fałszywą ścieżką. Po drugie, $?to niestabilny stan globalny - łatwo przez przypadek wyrzucić jego wartość. Na przykład, jeśli dodasz wiersz logowania, taki jak echo "Exit status is $?", nowa wartość w stanie $?się statusem wyjścia echo.
Charles Duffy
6
Inną opcją jest sprawdzenie zgodności wyrażeń regularnych w wyniku polecenia.
Na przykład:
[["$(./somecommand)"=~"sub string"]]&& echo "Output includes 'sub string'"
Odpowiedzi:
Przetestuj zwracaną wartość grep:
co jest wykonywane idiomatycznie, jak to:
i również:
źródło
=
bycia operatorem porównania, a nie==
; patrz pubs.opengroup.org/onlinepubs/9699919799/utilities/test.htmlgrep 'string' &>/dev/null
jest niezgodny z POSIX i znacznie wolniejszy do wykonania (jeślistring
pojawia się wcześnie w długim strumieniu wyjściowym) niżgrep -q string
. [Zastrzeżenie polega na tym, że jeśli chcesz mieć pewność,somecommand
że działa nawet po wyemitowaniustring
, w takim przypadku użyciegrep -q
- poprzez zamknięcie standardowego wejścia i wyjście po pierwszym wystąpieniustring
- może przynieść efekt przeciwny do zamierzonego]. (Re: "niezgodne z POSIX",&>
to rozszerzenie - patrz pubs.opengroup.org/onlinepubs/009695399/utilities/ ... opisujące obsługę przekierowań narzuconych przez POSIX).Testowanie
$?
jest anty-wzorcemźródło
grep -Fxq
F oznacza stałe (nie interpretować) i X na całej linii$?
jest anty-wzorcem?$?
nie ustawia poprzednich poleceń jako „sprawdzonych” dla celówset -e
lubERR
pułapki, więc twój program może zakończyć się w przypadkach, gdy chcesz, aby po prostu powrócił później celowo fałszywą ścieżką. Po drugie,$?
to niestabilny stan globalny - łatwo przez przypadek wyrzucić jego wartość. Na przykład, jeśli dodasz wiersz logowania, taki jakecho "Exit status is $?"
, nowa wartość w stanie$?
się statusem wyjściaecho
.Inną opcją jest sprawdzenie zgodności wyrażeń regularnych w wyniku polecenia.
Na przykład:
źródło
Czysty warunkowy skrypt powłoki if / else:
źródło