Co robi -e w shebang bash?

32

Mam skrypt bash z następującymi elementami:

#!/bin/bash -e

egrep "^username" /etc/passwd >/dev/null 
if[ $? -eq 0 ] 
then 
  echo "doesn't exist" 
fi

Ten skrypt nie będzie działał bez -e. Co robi -eten skrypt? Co również robi $?w tym kontekście?

Chris Henry
źródło
1
Dziwny. Nie -ena stronie podręcznika (naprawdę chcę zobaczyć odpowiedź na to pytanie). $?zawiera ostatni kod zakończenia (kod egrepprocesu spawnowanego powyżej).
2
@pst: -ejest udokumentowane pod set.
Greg Hewgill
Możesz uprościć skrypt, wykonując następujące czynności:if egrep -q "^username" /etc/passwd ; then echo "doesn't exist" ; fi
bollovan
2
Brakuje spacji między ifi [. Ten skrypt nie działa z -e , bo jeśli grepnie znajdzie niczego wtedy pod -eskryptu zakończy tam. Bez -etego wiadomość jest odwrócona: status ( $?) 0 oznacza, że ​​grep znalazł użytkownika. Zauważ, że tak na marginesie powinna to być nazwa użytkownika `grep '^: (a jeśli jest inny użytkownik o dłuższej nazwie?).
Gilles „SO- przestań być zły”
3
Będzie #/bin/bash -emiał taki sam efekt jak #/bin/bashna linii nr 1 i set -elinii nr 2?
blong

Odpowiedzi:

34

Błąd wyjścia. Więcej flag

Jeśli wystąpi błąd, natychmiast się zakończy.

$? to status wyjścia z poprzedniego polecenia. W systemie Linux status wyjścia równy 0 oznacza, że ​​polecenie zakończyło się powodzeniem. Każdy inny status oznaczałby błąd.

egrep "^ nazwa użytkownika" / etc / passwd> / dev / null Poszukałby nazwy użytkownika w pliku / etc / passwd. Jeśli go znajdzie, to status wyjścia $? będzie równa 0. Jeśli go nie znajdzie, stanem wyjścia będzie coś innego (nie 0), dlatego „echo nie istnieje”.


źródło
Ponadto możesz sprawić, aby skrypt działał poprawnie bez -e, zastępując pierwsze dwa wiersze znakiem if egrep "^username" /etc/passwd >/dev/null.
1
Dlaczego nie jest to setwymagane? : - /
1
@pst: Ponieważ -epodano bash jako argument wiersza poleceń. Wszystkie opcje wymienione poniżej setsą również akceptowane przez bash w wierszu poleceń - zwróć uwagę na pierwsze zdanie w sekcji Opcje strony podręcznika.
grawity
14

Wszystkie przełączniki linii poleceń bash są udokumentowane w man bash.

      -e Wyjdź natychmiast, jeśli potok (który może składać się z
              pojedyncza prosta komenda), komenda podpowłoki zawarta w
              nawiasy lub jedno z poleceń wykonanych jako część
              lista poleceń ujęta w nawiasy klamrowe (patrz SHELL GRAMMAR
              powyżej) wychodzi ze statusem niezerowym. Powłoka nie
              zakończ, jeśli polecenie, które się nie powiedzie, jest częścią polecenia
              lista bezpośrednio po chwili lub do słowa kluczowego,
              część testu po zastrzeżeniu if lub elif
              słowa, część dowolnego polecenia wykonanego w && lub || lista
              z wyjątkiem polecenia następującego po końcowym && lub ||, any
              polecenie w potoku, ale ostatnie, lub jeśli polecenie jest
              zwracana wartość jest odwracana za pomocą! Pułapka na ERR,
              jeśli ustawiony, jest wykonywany przed wyjściem powłoki. Ta opcja
              dotyczy środowiska powłoki i każdej środowiska podpowłoki
              osobno (zob. ŚRODOWISKO WYKONANIA POLECEŃ)
              powyżej) i może spowodować zamknięcie podpowłoki przed wykonaniem
              wszystkie polecenia w podpowłoce.
Greg Hewgill
źródło
2
Ahh Szukałem tego u człowieka, ale po znalezieniu -e w testach plików i braku -e przy głównych argumentach zrezygnowałem. Niezły fragment. Dlaczego nie jest to setwymagane? : - /
1

Twój skrypt jest niepoprawny, ponieważ

egrep "^username" /etc/passwd >/dev/null 
if[ $? -eq 0 ] 
then 
  #echo "doesn't exist" # WRONG
  echo "the USER EXISTS"
fi

status wyjścia 0 - średnia - wszystko jest OK, w przypadku grep oznacza „OK, znaleziono ciąg znaków”. status wyjścia! = 0 oznacza, że ​​coś jest nie tak, w przypadku grep 1 oznacza „nie znaleziono”, 2 oznacza „nie można otworzyć wejścia” ...

jm666
źródło