Как использовать сравнение файлов grep внутри инструкции bash if / else?

138

Когда наш сервер подойдет, нам нужно проверить файл, чтобы увидеть, как он настроен.

Мы хотим найти следующую строку в нашем файле /etc/aws/hosts.conf:

MYSQL_ROLE=master

Затем мы хотим проверить, существует ли эта строка, и использовать оператор if / else для запуска одного из двух вариантов в зависимости от того, существует ли строка или нет.

Каков синтаксис BASH для оператора if?

if [ ????? ]; then
  #do one thing
else
  #do another thing
fi
user77413
источник

Ответы:

205

От grep --help, но также см. Man grep :

Статус выхода равен 0, если была выбрана какая-либо строка, иначе 1; если возникает какая-либо ошибка и -q не указан, статус выхода равен 2.

if grep --quiet MYSQL_ROLE=master /etc/aws/hosts.conf; then
  echo exists
else
  echo not found
fi

Вы можете использовать более конкретное регулярное выражение, например ^MYSQL_ROLE=master$, чтобы избежать этой строки в комментариях, именах, которые просто начинаются с «master» и т. Д.

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


источник
> с нулевым значением true и ненулевым значением false - так же, как другие коды возврата интерпретируются оболочкой, и противоположно языку, подобному C., но почему противоположное ....?
kchoi 05
Потому что ноль обычно интерпретируется как «нет ошибки», а все остальное означает «некоторая ошибка». Если предполагается, что мы хотим знать, успешно ли завершилась команда.
timelmer
33

ifпринимает команду и проверяет ее возвращаемое значение. [это просто команда.

if grep -q ...
then
  ....
else
  ....
fi
Игнасио Васкес-Абрамс
источник
24

Обратите внимание, что для PIPEлюбой команды или последовательности команд:

if PIPE ; then
  # do one thing if PIPE returned with zero status ($?=0)
else 
  # do another thing if PIPE returned with non-zero status ($?!=0), e.g. error
fi 

Для записи [ expr ]- это встроенная оболочка сокращение для test expr.

Поскольку grepвозвращается со статусом 0 в случае совпадения и ненулевым статусом в случае отсутствия совпадений, вы можете использовать:

if grep -lq '^MYSQL_ROLE=master' ; then 
  # do one thing 
else 
  # do another thing
fi 

Обратите внимание, что использование -lwhich заботится только о том, чтобы файл имел хотя бы одно совпадение (так что он grepвозвращается, как только он находит одно совпадение, без необходимости продолжения синтаксического анализа входного файла).

на некоторых платформах [ expr ]не является встроенным, но фактически исполняемым /bin/[(чья последним аргументом будет ]), поэтому [ expr ]должны содержать пробела вокруг квадратных скобок, и почему он должен следовать одному из списка команд разделителей ( ;, &&, ||, |, &, новая линия)

владр
источник
4
-lявляется избыточным, grepвозвращается сразу после обнаружения любого совпадения с-q
Reinstate Monica Please
3

просто используйте bash

while read -r line
do
  case "$line" in
    *MYSQL_ROLE=master*)
       echo "do your stuff";;
    *) echo "doesn't exist";;      
  esac
done <"/etc/aws/hosts.conf"
призрачная собака74
источник