Jak użyć porównania pliku grep wewnątrz instrukcji bash if / else?


138

Kiedy pojawia się nasz serwer, musimy sprawdzić plik, aby zobaczyć, jak serwer jest skonfigurowany.

Chcemy wyszukać następujący ciąg w naszym pliku /etc/aws/hosts.conf:

MYSQL_ROLE=master

Następnie chcemy sprawdzić, czy ten ciąg istnieje, i użyć instrukcji if / else, aby uruchomić jedną z dwóch opcji w zależności od tego, czy ciąg istnieje, czy nie.

Jaka jest składnia BASH dla instrukcji if?

if [ ????? ]; then
  #do one thing
else
  #do another thing
fi

Odpowiedzi:


205

Od grep --help, ale zobacz także man grep :

Status wyjścia wynosi 0, jeśli wybrano jakąkolwiek linię, 1 w przeciwnym razie; jeśli wystąpi jakikolwiek błąd i nie podano -q, kod zakończenia wynosi 2.

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

Możesz chcieć użyć bardziej konkretnego wyrażenia regularnego, na przykład ^MYSQL_ROLE=master$, aby uniknąć tego ciągu w komentarzach, nazwach, które zaczynają się od słowa „wzorzec” itp.

Działa to, ponieważ if przyjmuje polecenie i uruchamia je, a następnie używa wartości zwracanej tego polecenia, aby zdecydować, jak postępować, przy czym zero oznacza prawdę, a niezerowe oznacza fałsz - tak samo jak inne kody powrotu są interpretowane przez powłokę, i przeciwieństwo języka takiego jak C.


> gdzie zero oznacza prawdę, a niezerowe oznacza fałsz - tak samo jak inne kody powrotu są interpretowane przez powłokę i jest przeciwieństwem języka takiego jak C., ale dlaczego jest odwrotnie…?
— kchoi

Ponieważ zero jest zwykle interpretowane jako „brak błędu”, podczas gdy cokolwiek innego oznacza „jakiś błąd”. Jeśli założymy, chcemy wiedzieć, czy polecenie zakończyło się pomyślnie.
— timelmer


23

Zauważ, że aby PIPEbyć dowolnym poleceniem lub sekwencją poleceń, to:

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 

Dla przypomnienia, [ expr ]jest to powłoka wbudowane † skrót dla test expr.

Ponieważ grepzwraca status 0 w przypadku dopasowania i niezerowy stan w przypadku braku dopasowań, możesz użyć:

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

Zauważ, że użycie -lktórego dotyczy tylko tego, że plik ma co najmniej jedno dopasowanie (tak, że greppowraca, gdy tylko znajdzie jedno dopasowanie, bez niepotrzebnego dalszego analizowania pliku wejściowego).

† na niektórych platformach [ expr ]nie jest wbudowana, ale rzeczywisty wykonywalny /bin/[(którego ostatni argument będzie ]), dlatego [ expr ]powinien zawierać spacje wokół nawiasach kwadratowych, a dlaczego to musi być przestrzegane przez jednego z separatorami lista komend ( ;, &&, ||, |, &, Nowa linia)


4
-ljest zbędny, grepwraca natychmiast po znalezieniu dowolnego dopasowania z-q
— Przywróć Monica Please

3

po prostu użyj basha

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"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.