Проверка, содержит ли вывод команды определенную строку в сценарии оболочки

Я пишу сценарий оболочки и пытаюсь проверить, содержит ли вывод команды определенную строку. Я думаю, что я, вероятно, должен использовать grep, но я не уверен, как. Кто-нибудь знает?

6 ответов

Решение

Проверьте возвращаемое значение 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'

Тестирование $? это анти-шаблон

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

Другой вариант - проверить соответствие регулярного выражения в выводе команды.

Например:

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

Чистый сценарий условной оболочки if/else:

if ./somecommand | grep -q 'some_string'; then
  echo "exists"
else
  echo "doesn't exist"
fi

КОРОТКИЙ ОТВЕТ

Все приведенные выше (очень отличные) ответы предполагают, что они могут «видеть» вывод команды, что не всегда верно:

SUCCESS может быть отправлен в STDOUT , а FAILURE — в STDERR.

Поэтому в зависимости от того, в каком направлении вы тестируете, вы можете потерпеть неудачу. Это означает, что если вы тестируете случай FAILURE , вы должны перенаправить вывод команды в STDOUT, используя в таком случае, как этот.

ДЛИННЫЙ ОТВЕТ с ДОКАЗАТЕЛЬСТВАМИ

У меня было то, что я считал очень простым тестом в сценарии bash с использованием и это продолжало терпеть неудачу. Затем последовало сильное почесывание головы. Использование в моем скрипте выяснилось, что переменная была пустой! Поэтому я создал следующий тест, чтобы понять, как что-то ломается.

ПРИМЕЧАНИЕ . Это инструмент Linux из пакета « open-iscsi », используемый для подключения/отключения хоста к хранилищу SAN. Команда используется, чтобы показать, установлены ли какие-либо соединения LUN):

      #!/bin/bash

set -x

TEST1=$(iscsiadm -m session)
TEST2=$(iscsiadm -m session 2>&1)
echo
echo 'Print TEST1'
echo $TEST1
echo
echo 'Print TEST2'
echo $TEST2
echo

Если LUN БЫЛ подключен, ОБЕ переменные были успешно заполнены значениями:

      Print TEST1
tcp: [25] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:ipdisk.Target-LUN1 (non-flash) tcp: [26] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:storagehost.Target-LUN1 (non-flash)

Print TEST2
tcp: [25] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:ipdisk.Target-LUN1 (non-flash) tcp: [26] 192.168.X.XX:3260,1 iqn.2000-01.com.synology:storagehost.Target-LUN1 (non-flash)

Однако, если LUN НЕ БЫЛ подключен, выходные данные отправлялись в STDERR, и заполнялась только переменная « TEST2 », где мы перенаправляли на STDOUT с помощью ; Переменная " TEST1 ", у которой не было перенаправления на STDOUT, была пустой:

      iscsiadm: No active sessions.

Print TEST1


Print TEST2
iscsiadm: No active sessions.

ВЫВОД

Если у вас навороченный, наполовину сломанный - работает в одном направлении, но не в другом - ситуация подобна этой, попробуйте вышеописанный тест заменить с вашей собственной командой, и вы должны получить надлежащую видимость, чтобы переписать свой тест, чтобы он работал правильно.

Это кажется более очевидным, не так ли?

      # Just a comment... Check if output of command is hahaha
MY_COMMAND_OUTPUT="$(echo hahaha)"
if [[ "$MY_COMMAND_OUTPUT" != "hahaha" ]]; then
  echo "The command output is not hahaha"
  exit 2
else
  echo "The command output is hahaha"
fi
Другие вопросы по тегам