Uruchom dwa polecenia w przypadku || lub &&

11

Czytałem o && i || i chciałbym uruchomić dwa polecenia w fałszywym przypadku.

Próbowałem, ;ale to działa zawsze . Próbowałem umieścić go w nawiasach klamrowych, { command1; command2 }ale powoduje to błąd składniowy.

Chcę zrobić coś takiego

command && echo "Ok, continuing" || echo "Check internet connection"; exit 1

który jest wyłączany tylko wtedy, gdy nie ma połączenia z Internetem.

Thomas Weller
źródło
1
To wydaje się zwykłym błędem typograficznym. O wiele bardziej interesujące pytanie to różnice między ()i {}.
edwinksl,

Odpowiedzi:

27

Korzystanie z parens umieszcza polecenia w podpowłoce, która nie zawsze jest tym, czego chcesz. Alternatywnie użyj nawiasów klamrowych:

command && echo "Ok, continuing" || { echo "Check internet connection"; exit 1; }

Sztuczka polega na tym, że w przeciwieństwie do parens, po ostatnim poleceniu w nawiasach klamrowych musi nastąpić ;.

Dlaczego wymagany jest średnik lub znak nowej linii

Nawias klamrowy jest prawidłowym argumentem dla polecenia. Na przykład tutaj jest nawias klamrowy jako argument do echo:

$ echo }
}

W konsekwencji, jeśli powłoka zobaczy:

{ command1; command2 }

Powłoka interpretuje polecenie 1 jako brak argumentów, a polecenie 2 jako jeden argument składający się ze znaku }. Nawias klamrowy }jest interpretowany jako zamykanie grupy tylko wtedy, gdy następuje po średniku lub nowej linii. Aby powyższe zadziałało:

{ command1; command2; }

Podkładki i różnica między {...}i(...)

Zauważ, że następujące zestawy xto 10, ale to ustawienie jest zapomniane przed uruchomieniem echopolecenia:

$ x=0; false || ( echo Hello; x=10 )
Hello
$ echo $x
0

Natomiast w przypadku nawiasów klamrowych x=10zapamiętywane jest ustawienie :

$ x=0; false || { echo Hello; x=10; }
Hello
$ echo $x
10

Różnica polega na tym, że przypisania zmiennych w podpowłoce nie są zachowywane po zakończeniu podpowłoki.

Dokumentacja

Od man bash:

(lista)

lista jest wykonywana w środowisku podpowłoki (patrz ŚRODOWISKO WYKONYWANIA POLECEŃ poniżej). Zmienne przypisania i wbudowane polecenia, które wpływają na środowisko powłoki, nie pozostają aktywne po zakończeniu polecenia. Status powrotu to status wyjścia z listy.

{lista; }

lista jest po prostu wykonywana w bieżącym środowisku powłoki. lista musi być zakończona znakiem nowej linii lub średnikiem. Jest to znane jako polecenie grupowe. Status powrotu to status wyjścia z listy. Zauważ, że w przeciwieństwie do metaznaków (i), {i} są słowami zastrzeżonymi i muszą wystąpić, gdy słowo zastrzeżone może zostać rozpoznane. Ponieważ nie powodują podziału słów, muszą być oddzielone od listy spacją lub innym metaznakiem powłoki.

[Podkreślenie dodane]

John1024
źródło