Проверка, содержит ли вывод команды определенную строку в сценарии оболочки
117
Я пишу сценарий оболочки и пытаюсь проверить, содержит ли вывод команды определенную строку. Я думаю, мне, вероятно, придется использовать grep, но я не знаю, как это сделать. Кто-нибудь знает?
Должна ли команда продолжать работу после генерации искомой выходной строки или ее можно сразу закрыть в это время? (В этом отношении ваши два ответа различаются семантикой).
Кроме того, grep 'string' &>/dev/nullон несовместим с POSIX и намного медленнее выполняется (если stringпоявляется в начале длинного выходного потока), чем grep -q string. [Предостережение, если вы хотите быть уверенным, что somecommandпродолжает работать даже после отправки string, и в этом случае использование grep -q- путем закрытия его стандартного ввода и выхода после того, как будет обнаружен первый экземпляр string- может быть контрпродуктивным]. (Re: «несовместимо с POSIX» &>- это расширение - см. Pubs.opengroup.org/onlinepubs/009695399/utilities/…, где описывается поддержка перенаправления, предписанная POSIX).
Чарльз Даффи
Помогло бы, если бы было объяснено, почему это работает / что делает каждый параметр, чтобы способствовать полному пониманию синтаксиса
Если случайно вы хотите проверить только фиксированную строку, добавьте параметры F и x : grep -FxqF означает фиксированный (не интерпретируемый), а x для всей строки
Erdal G.
4
Почему тестирование $?антипаттерна?
Виталий Зданевич
1
@VitalyZdanevich Я полагаю, потому что он не устойчив к параллелизму.
Конрад Райх
@VitalyZdanevich, например, тестирование $?не устанавливает предыдущие команды как "проверенные" для целей set -eили ERRловушки, поэтому ваша программа может выйти в тех случаях, когда вы хотите, чтобы она просто вернулась по намеренно ложному пути позже. С другой стороны, $?глобальное состояние изменчиво - его значение легко случайно выбросить. Например, если вы добавите в журнал строку вроде echo "Exit status is $?", новое значение в $?станет статусом выхода echo.
Чарльз Даффи,
6
Другой вариант - проверить соответствие регулярного выражения в выводе команды.
Например:
[["$(./somecommand)"=~"sub string"]]&& echo "Output includes 'sub string'"
Ответы:
Проверьте возвращаемое значение grep:
что идиоматически делается так:
а также:
источник
=
оператора сравнения, но не==
; см. pubs.opengroup.org/onlinepubs/9699919799/utilities/test.htmlgrep 'string' &>/dev/null
он несовместим с POSIX и намного медленнее выполняется (еслиstring
появляется в начале длинного выходного потока), чемgrep -q string
. [Предостережение, если вы хотите быть уверенным, чтоsomecommand
продолжает работать даже после отправкиstring
, и в этом случае использованиеgrep -q
- путем закрытия его стандартного ввода и выхода после того, как будет обнаружен первый экземплярstring
- может быть контрпродуктивным]. (Re: «несовместимо с POSIX»&>
- это расширение - см. Pubs.opengroup.org/onlinepubs/009695399/utilities/…, где описывается поддержка перенаправления, предписанная POSIX).Тестирование
$?
- это антипаттернисточник
grep -Fxq
F означает фиксированный (не интерпретируемый), а x для всей строки$?
антипаттерна?$?
не устанавливает предыдущие команды как "проверенные" для целейset -e
илиERR
ловушки, поэтому ваша программа может выйти в тех случаях, когда вы хотите, чтобы она просто вернулась по намеренно ложному пути позже. С другой стороны,$?
глобальное состояние изменчиво - его значение легко случайно выбросить. Например, если вы добавите в журнал строку вродеecho "Exit status is $?"
, новое значение в$?
станет статусом выходаecho
.Другой вариант - проверить соответствие регулярного выражения в выводе команды.
Например:
источник
Чистый сценарий условной оболочки if / else:
источник