Jaki jest cel „&&” w poleceniu powłoki?


Odpowiedzi:


398

&&pozwala ci zrobić coś w oparciu o to, czy poprzednie polecenie zakończyło się powodzeniem - dlatego zazwyczaj widzisz, że jest to powiązane do_something && do_something_else_that_depended_on_something.


391

Co więcej, masz także ||logiczne lub, a także ;separator, który nie przejmuje się tym, co stało się wcześniej z poleceniem.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Niektóre szczegóły na ten temat można znaleźć tutaj Listy poleceń w podręczniku Bash.


5
Może chciałbyś dodać false && echo "Will not be printed".
MTSan

112

wiersz poleceń - do czego służy &&?

W skorupce, kiedy widzisz

$ command one && command two

celem jest wykonanie polecenia następującego po tym, &&tylko jeśli pierwsze polecenie zakończy się powodzeniem. Jest to idiomatyczne dla pocisków Posix i nie tylko w Bash.

Ma to na celu zapobieganie uruchomieniu drugiego procesu, jeśli pierwszy się nie powiedzie.

Możesz zauważyć, że użyłem słowa „zamiar” - to nie bez powodu. Nie wszystkie programy zachowują się tak samo, więc aby to zadziałało, musisz zrozumieć, co program uważa za „awarię” i jak sobie z tym poradzić, czytając dokumentację i, w razie potrzeby, kod źródłowy.

Twoja powłoka przyjmuje wartość zwracaną 0 dla wartości true, a inne liczby dodatnie dla wartości false

Programy zwracają sygnał przy wychodzeniu. Powinny zwrócić 0, jeśli zakończą się pomyślnie, lub większą od zera, jeśli nie. Umożliwia to ograniczoną komunikację między procesami.

&&Się dalej AND_IFw gramatyki POSIX powłoki , która jest częścią and_orlisty rozkazów, które należą również ||która jest OR_IFo podobnej semantyki.

Symbole gramatyczne cytowane z dokumentacji:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

I gramatyka (cytowana również z dokumentacji), która pokazuje, że dowolną liczbę AND_IFs ( &&) i / lub OR_IFs ( ||) można łączyć razem (zgodnie z and_ordefinicją rekurencyjną):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Oba operatory mają jednakowe pierwszeństwo i są oceniane od lewej do prawej (są one skojarzone). Jak mówią doktorzy:

AND-ORLista sekwencji jednej lub więcej rur, oddzielonych przez operatorów "&&"i "||".

Lista jest sekwencja z jednego lub więcej i, lub listy oddzielone przez operatorów ';'i '&'ewentualnie zakończone ';', '&'lub.

Operatorzy "&&"i "||"mają równy priorytet i będą oceniani z pozostawionym skojarzeniem. Na przykład oba poniższe polecenia zapisują wyłącznie pasek na standardowe wyjście:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. W pierwszym przypadku false to polecenie kończące się ze statusem 1

    $ false
    $ echo $?
    1

    co oznacza, echo fooże nie działa (tj. zwarcie echo foo). Następnie polecenie echo barjest wykonywane.

  2. W drugim przypadku true kończy działanie z kodem 0

    $ true
    $ echo $?
    0

    i dlatego echo foonie jest wykonywany, a następnie echo barwykonywany.


31

Dość powszechnym zastosowaniem „&&” jest kompilowanie oprogramowania za pomocą narzędzi automatycznych. Na przykład:

./configure --prefix=/usr && make && sudo make install

Zasadniczo, jeśli konfiguracja się powiedzie, make jest uruchamiany w celu skompilowania, a jeśli to się powiedzie, make jest uruchamiany jako root, aby zainstalować program. Używam tego, kiedy jestem pewien, że wszystko będzie działać, i pozwala mi to robić inne ważne rzeczy, takie jak przeglądanie przepływu stosu, a nie „monitorowanie” postępu.

Czasami naprawdę mnie pociąga ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Robię to, gdy na przykład robię Linuksa od podstaw.


2
Dobry w REPL, ale dla skryptów wolałbym set -o errexitBash.
Franklin Yu

19

&&ciągi poleceń razem. Kolejne polecenia są wykonywane tylko wtedy, gdy poprzednie się powiedzą.

Podobnie ||pozwoli na wykonanie kolejnej komendy, jeśli poprzednie nie powiedzie się.

Zobacz Programowanie powłoki Bash .


8

Zobacz przykład:

mkdir test && echo "Something" > test/file

Shell spróbuje utworzyć katalog, testa następnie, tylko jeśli się powiedzie , spróbuje utworzyć w nim plik.

Możesz więc przerwać sekwencję kroków, jeśli jeden z nich się nie powiedzie.


8

Wykonuje drugie polecenie, jeśli pierwsze zdanie zakończy się pomyślnie. Jak instrukcja if:

 if (1 == 1 && 2 == 2)
  echo "test;"

Najpierw próbuje, jeśli 1 == 1, jeśli to prawda, sprawdza, czy 2 == 2


1
Czy ktoś mógłby wyjaśnić, dlaczego zostało to odrzucone, ponieważ użytkownicy natknęli się na to pytanie?
user3243242,

1
@ user3243242 to nie jest źle, tylko słaby przykład ilustrujący użycie&&
dan

To świetny wgląd w działanie iftestów w bash. Nigdy nie myślałem o tym jak o łańcuchu poleceń porównawczych, które łamią się, gdy któreś z nich zawodzi. Więc mam moje poparcie :)
PiRK

1
Konsekwencją jest to, że można uzyskać odwrotne zachowanie za pomocą ||polecenia, aby połączyć polecenia, dopóki jedno z nich się nie powiedzie: eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2: wykonaj polecenie_2 tylko po pomyślnym wykonaniu polecenia_1.

command_1 || command_2: wykonaj polecenie_2 tylko wtedy, gdy wykonanie polecenia_1 nie powiodło się.

Czuje się podobnie, jak warunek „if” jest wykonywany w głównym języku programowania, np. W if (condition_1 && condition_2){...}warunku_2 zostanie pominięty, jeśli warunek_1 jest, falseaw if (condition_1 || condition_2){...}warunku_2 zostanie pominięty, jeśli warunek_1 jest true. Zobacz, to ta sama sztuczka, której używasz do kodowania :)


Nie wiem, co rozumiesz przez „dokładnie odwrotnie”, ale $ echo „1” || echo „2” drukuje tylko „1”. i $ źle_polecenie || echo „2” wypisuje komunikat o błędzie, a „2” w następnym wierszu. Czy mógłbyś wyjaśnić nieco więcej, co według ciebie jest w tym złego?
Xiaonin Li

stary, z pewnością byłem wczoraj zbyt zmęczony. przepraszam za to, to tylko ja: / Potrzebuję, abyś coś w tobie odpowiedział, jeśli chcesz głosować (aby uzyskać odpowiedź 0, w tej chwili stackoverflow poprosić o edycję, więc nie mogę)
Arount

@Arount, w porządku, nie martw się. Właśnie przesłałem edycję. więc czy możesz teraz usunąć głosowanie negatywne?
Xiaonin Li

tak, jeszcze raz przepraszam, naprawdę
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Gdy program sprawdza, czy polecenie, następnie program tworzy liczbę o nazwie kod wyjścia, jeśli oba warunki są spełnione, kod wyjścia wynosi zero (0), w przeciwnym razie kod wyjścia jest liczbą dodatnią. tylko przy wyświetlaniu Równa, jeśli kod wyjścia jest generowany jako zero (0), co oznacza, że ​​oba warunki są spełnione.


Witamy w Stackoverflow. Przed opublikowaniem tutaj upewnij się, że fragment kodu działa. Musisz to poprawićif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu

1
Dziękuję @ZhengQu za polecenie, zostało zrobione.
Amin
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.