Który z nich jest lepszy: using; lub &&, aby wykonać wiele poleceń w jednym wierszu?

427

W tutorialach i instrukcjach często widzę łączone polecenia. Na przykład,

sudo apt-get update && sudo apt-get install pyrenamer

Wydaje się, że cztery możliwe złącza: &, &&, ||i ;. Chociaż & złącze jest dla mnie jasne (wysyła proces do tła i pozostawia terminal dostępny), nie jest jasne, jaka jest różnica między &&i ;. I nie wiedziałem o tym, ||dopóki komentarz Kaya nie był.

Poniższe pytania dotyczą różnicy między dwoma złączami, ale najczęściej w komentarzach:

Oto kilka powiązanych pytań:

  1. Jaka jest różnica między ;i &&?
  2. Kiedy należy ich odpowiednio używać ? Przyjemnie byłoby zobaczyć kilka przypadków użycia: jeśli chcę uruchomić polecenie, a następnie po jego zamknięciu komputera, które złącze wybrać?
  3. Jakie są ich zalety i niebezpieczeństwa ? Robie Basak wspomina w komentarzu do tej odpowiedzi, że na przykład polecenie cd /somewhere_else; rm -Rf *może mieć destrukcyjne konsekwencje, jeśli na przykład zawiedzie pierwszy element w łańcuchu poleceń.
  4. Jeśli dotyczy, skąd pochodzą?
don.joey
źródło
7
Istnieje inne złącze, z którym być może nie spotkałeś: ||jest to samo, &&z wyjątkiem tego, że wykonuje drugie polecenie tylko wtedy, gdy pierwsze zakończyło pracę z niezerowym (nieudanym) statusem.
Kaya
4
Zauważ też, że uruchomienie skryptu set -espowoduje zatrzymanie skryptu w przypadku awarii, tak jakby wszystkie polecenia były połączone &&.
choroba
stackoverflow.com/questions/3573742/...
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
3
Nikt nie odpowiedział na pytanie 4 ... Podejrzewam zachowanie && i || został zainspirowany językiem programowania C. W przypadku (x && y), jeśli x ma wartość false, całe wyrażenie musi być fałszywe, aby kompilator mógł zoptymalizować ocenę y, na wypadek gdyby była droga. Współczesne standardy C i C ++ faktycznie wymagają tej optymalizacji, więc programy mogą bezpiecznie założyć, że y nie zostanie ocenione, jeśli x jest fałszem. Na przykład (ptr && ptr-> dni> 31) nie ulegnie awarii, nawet jeśli ptr ma wartość null. Również w C instrukcje kończą się na; niezależnie od tego, czy w tym samym wierszu znajduje się inne zdanie, czy nie.
Kevin

Odpowiedzi:

771

Ściągawka:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.
Jacek
źródło
19
I oczywiście A & B &: Uruchom A w tle, następnie uruchom B w tle (niezależnie od sukcesu) i zwróć kontrolę nad powłoką. Często działa to tak samo, jak uruchamianie obu procesów jednocześnie.
Ograniczone Zadośćuczynienie
4
czy można powiedzieć: uruchomić w tle, a następnie b w tle tylko, jeśli działał? (Chyba &&&?)
user230910
14
@ user230910: to by było (A && B) &.
leftaroundabout
5
Czy możesz odwołać się do tego wiarygodnego dokumentu?
Jaime Hablutzel,
@Jack Wykonany z Cronjob, nie do końca przestrzega tej zasady, jakiś pomysł, dlaczego? W przypadku pliku python
CodeGuru,
77

&&uruchamia drugie polecenie tylko wtedy, gdy pierwsze zostało zakończone ze statusem 0 (powiodło się). ;uruchamia oba polecenia, nawet jeśli pierwsze zakończy działanie z niezerowym statusem.

Twój przykład z &&może być równoważnie sparafrazowany jako

if sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi
choroba
źródło
Dzięki. Zaktualizowałem pytanie, aby zapewnić łatwe rozróżnienie różnych pytań.
don.joey
5
@Prywatne: powinieneś użyć, ;jeśli drugie polecenie nie wymaga poprzedniego, aby odnieść sukces.
choroba
31

Użycie ;spowoduje wykonanie poleceń niezależnie od tego, czy pierwsze polecenie zakończy się powodzeniem, czy nie.

za pomocą &&polecenia wykonania 2. polecenia tylko wtedy, gdy pierwsze polecenie zostało wykonane pomyślnie (status 0).

Oba są używane z innej perspektywy. Jak w przypadku dłuższego procesu, powiedz, że w przypadku instalacji musisz ją skompilować i zainstalować. zalecana make && make install. Instalacja rozpocznie się tylko po makepomyślnym zakończeniu .

Dlatego w przypadku poleceń zależnych powinieneś użyć &&

Wring Bash lub użycie poleceń z niezależnymi poleceniami ;

Więc jeśli chcesz zamknąć komputer, nawet pierwsze zadanie nie powiodło się ;, ale jeśli chcesz po pełnym sukcesie pierwszego zadania zainicjuj zamknięcie&&

Web-E
źródło
14

a ; bbędzie działać b niezależnie od statusu wyjścia a. a && buruchomi b tylko jeśli się powiedzie.

Jest to konieczne i wystarczające, aby odpowiedzieć na pierwsze 3 pytania. W szczególności 2 jest zbyt szerokie i nie można na nie odpowiedzieć „jedną”, ostateczną odpowiedzią - najlepiej postawić na podstawie indywidualnych przypadków.

Co do czwartego pytania: Składnia Bash .

Korzystanie z nich nie wiąże się z żadnym niebezpieczeństwem. Ponownie powyższa definicja jest wystarczająca. Oznacza to, że napiszesz, &&gdy bma niezamierzone skutki, jeśli asię nie powiedzie. IMHO nie wymaga dalszych zasad ani wyjaśnień.

ignis
źródło
1

ZA; B # Uruchom A, a następnie B, niezależnie od sukcesu A

A && B # Uruchom B, jeśli i tylko jeśli A się powiedzie

A || B # Uruchom B, jeśli i tylko jeśli A się nie powiedzie

A i # Uruchom A w tle.

Bardzo dobra zasada. Dodałbym, że w niektórych przypadkach użycie tych poleceń w podpowłoce ma sens, gdy chcemy rozważyć je jako pojedynczą jednostkę lub nie chcemy powiązać niektórych wyników operacji z bieżącą powłoką.

Przykłady:

-concatenate wyjście dwóch poleceń:

(ls foo; ls bar) > single-result.txt

-wchodzenie do katalogu i wykonywanie stamtąd polecenia bez zmieniania bieżącego katalogu powłoki:

(cd target-directory && jar -xf ../my-jar)
davidxxx
źródło