Перевірка, чи висновок команди містить певний рядок у сценарії оболонки


116

Я пишу скрипт оболонки, і я намагаюся перевірити, чи містить результат команди певний рядок. Я думаю, що, мабуть, треба використовувати греп, але не знаю як. Хтось знає?


Чи потрібно команді продовжувати працювати після генерації вихідного рядка, який ви шукаєте, чи його можна негайно закрити? (Ваші дві відповіді в цьому відношенні відрізняються за своєю семантикою).
Чарльз Даффі

Відповіді:


97

Перевірте повернене значення grep:

./somecommand | grep 'string' &> /dev/null
if [ $? == 0 ]; then
   echo "matched"
fi

що робиться ідіоматично так:

if ./somecommand | grep -q 'string'; then
   echo "matched"
fi

і також:

./somecommand | grep -q 'string' && echo 'matched'

2
Цей код не працює з усіма оболонками POSIX: Стандарт POSIX вимагає лише =оператора порівняння, а не ==; дивіться pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html
Чарльз Даффі

4
Крім того, grep 'string' &>/dev/nullце сумісність, не сумісна з POSIX, і виконувати її набагато повільніше (якщо вона stringз'являється рано в довгому вихідному потоці), ніж grep -q string. [Застереження є, якщо ви хочете бути впевненим, що він somecommandпродовжує працювати навіть після випромінювання string; у цьому випадку використання grep -q- закривши його stdin та вийшовши після того, stringяк побачено перший екземпляр - може бути контрпродуктивним]. (Re: "не сумісний з POSIX", &>є розширенням - див. Pubs.opengroup.org/onlinepubs/009695399/utilities/…, що описує підтримку перенаправлення, накладене POSIX).
Чарльз Даффі

Допоможе, якби було пояснено, чому це працює / що робить кожен параметр, щоб заохотити повне розуміння синтаксису
redfox05

157

Тестування $?є анти-закономірністю

if ./somecommand | grep -q 'string'; then
  echo "matched"
fi

Якщо випадково ви хочете протестувати лише фіксовану рядок, додайте параметри F і x : grep -Fxq F означає фіксовану (не інтерпретовану), а x для всього рядка
Ердаль Г.

4
Чому тестування $?анти-шаблон?
Віталій Зданевич

1
@VitalyZdanevich Я припускаю, тому що це не надійно проти одночасності.
Конрад Рейче

@VitalyZdanevich, наприклад, тестування $?не встановлює попередні команди як "перевірені" для цілей set -eабо ERRпастки, тому ваша програма може вийти із випадків, коли ви хочете, щоб вона просто повернулася навмисно помилковим шляхом пізніше. З іншого боку, $?мінлива глобальна держава - легко скинути її цінність випадково. Наприклад, якщо ви додасте такий рядок журналу, як echo "Exit status is $?"нове, нове значення в $?набуває статусу виходу echo.
Чарльз Даффі

6

Інший варіант - перевірити відповідність регулярного вираження на командному виході

Наприклад:

[[ "$(./somecommand)" =~ "sub string" ]] && echo "Output includes 'sub string'"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.