Jakie są operatory kontroli i przekierowania powłoki?

245

Często widzę samouczki online, które łączą różne polecenia z różnymi symbolami. Na przykład:

command1 |  command2
command1 &  command2
command1 || command2    
command1 && command2

Inne wydają się łączyć polecenia z plikami:

command1  > file1
command1  >> file1

Co to za rzeczy? Jak one się nazywają? Co oni robią? Czy jest ich więcej?


Meta wątek na ten temat. .

terdon
źródło

Odpowiedzi:

340

Są to tak zwane operatory powłoki i tak, jest ich więcej. Przedstawię krótki przegląd najczęstszych wśród dwóch głównych klas, operatorów sterujących i operatorów przekierowujących , oraz ich działania w odniesieniu do powłoki bash.

A. Operatorzy kontroli

W języku poleceń powłoki: token pełniący funkcję kontrolną.
Jest to jeden z następujących symboli:

&   &&   (   )   ;   ;;   <newline>   |   ||

I |&w bash.

!To nie operator kontrola ale słowo zastrzeżone . Staje się logicznym NIE [operatorem negacji] w wyrażeniach arytmetycznych i konstrukcjach testowych (wciąż wymagając separatora spacji).

A.1 Lista terminatorów

  • ; : Wykona jedno polecenie po zakończeniu, niezależnie od wyniku pierwszego.

    command1 ; command2

    Pierwszy command1jest uruchamiany na pierwszym planie, a po jego zakończeniu command2będzie uruchamiany.

    Znak nowej linii, który nie jest literałem ciągu lub po określonych słowach kluczowych, nie jest równoważny operatorowi średnika. Lista ;rozdzielonych prostych poleceń jest wciąż listą - tak jak w parserze powłoki musi nadal czytać proste polecenia, które ;poprzedzają rozdzielone proste polecenie przed wykonaniem, podczas gdy nowy wiersz może wyznaczyć całą listę poleceń - lub listę list. Różnica jest subtelna, ale skomplikowana: biorąc pod uwagę, że powłoka nie ma wcześniejszej konieczności odczytu danych po nowej linii, nowa linia oznacza punkt, w którym powłoka może zacząć oceniać proste polecenia, które już odczytała, podczas gdy ;średnik robi nie.

  • & : Uruchomi to polecenie w tle, umożliwiając kontynuowanie pracy w tej samej powłoce.

     command1 & command2

    Tutaj command1jest uruchamiany w tle i command2natychmiast uruchamia się na pierwszym planie, nie czekając na command1wyjście.

    Nowa linia po command1jest opcjonalna.

A.2 Operatory logiczne

  • && : Służy do budowania list ORAZ, pozwala uruchomić jedno polecenie tylko wtedy, gdy inne zakończyło się pomyślnie.

     command1 && command2

    Tutaj command2uruchomi się po command1zakończeniu i tylko wtedy, gdy się command1powiedzie (jeśli kod wyjścia wynosił 0). Oba polecenia są uruchamiane na pierwszym planie.

    To polecenie można również zapisać

    if command1
    then command2
    else false
    fi

    lub po prostu, if command1; then command2; fijeśli status zwrotu jest ignorowany.

  • || : Służy do budowania list LUB, pozwala uruchomić jedno polecenie tylko wtedy, gdy inne zakończyło się niepowodzeniem.

     command1 || command2

    Tutaj command2będzie działać tylko w przypadku command1niepowodzenia (jeśli zwróci status wyjścia inny niż 0). Oba polecenia są uruchamiane na pierwszym planie.

    To polecenie można również zapisać

    if command1
    then true
    else command2
    fi

    lub w skrócie if ! command1; then command2; fi.

    Zauważ, że &&i ||są lewostronne; patrz Pierwszeństwo operatorów logicznych powłoki &&, || po więcej informacji.

  • !: To słowo zastrzeżone, które działa jak operator „nie” (ale musi mieć ogranicznik), używane do zanegowania zwracanego statusu polecenia - zwróć 0, jeśli polecenie zwraca stan niezerowy, zwróć 1, jeśli zwróci status 0 Również logiczne NIE dla testnarzędzia.

    ! command1
    
    [ ! a = a ]

    I prawdziwy operator NOT w wyrażeniach arytmetycznych:

    $ echo $((!0)) $((!23))
    1 0

A.3 Operator rur

  • |: Operator potoku przekazuje dane wyjściowe jednego polecenia jako dane wejściowe do drugiego. Polecenie zbudowany z rur operatora nazywana jest rurociąg .

     command1 | command2

    Każde wydrukowane wyjście command1jest przekazywane jako dane wejściowe do command2.

  • |&: To jest skrót 2>&1 |w bash i zsh. Przekazuje zarówno standardowe wyjście, jak i standardowy błąd jednego polecenia jako dane wejściowe do drugiego.

    command1 |& command2

A.4 Inne znaki interpunkcyjne na liście

;;służy wyłącznie do oznaczenia końca instrukcji case . Ksh, bash i zsh również obsługują ;&przechodzenie do następnego przypadku i ;;&(nie w ATT ksh), aby kontynuować i przetestować kolejne przypadki.

(i )służą do grupowania poleceń i uruchamiania ich w podpowłoce. {a }także grupować polecenia, ale nie uruchamiaj ich w podpowłoce. Zobacz tę odpowiedź do dyskusji na temat różnych rodzajów nawiasów klamrowych w nawiasach i składni powłoki.

B. Operatorzy przekierowań

Operator przekierowania

W języku poleceń powłoki: token pełniący funkcję przekierowania. Jest to jeden z następujących symboli:

<     >     >|     <<     >>     <&     >&     <<-     <>

Pozwalają one kontrolować dane wejściowe i wyjściowe poleceń. Mogą pojawiać się w dowolnym miejscu w ramach prostego polecenia lub mogą następować po poleceniu. Przekierowania są przetwarzane w kolejności, w jakiej się pojawiają, od lewej do prawej.

  • < : Daje dane wejściowe do polecenia.

    command < file.txt

    Powyższe zostanie wykonane commandna podstawie zawartości file.txt.

  • <>: tak samo jak powyżej, ale plik jest otwarty w trybie odczytu + zapisu zamiast tylko do odczytu :

    command <> file.txt

    Jeśli plik nie istnieje, zostanie utworzony.

    Ten operator jest rzadko używany, ponieważ polecenia na ogół odczytują tylko ze standardowego wejścia, choć może się przydać w wielu konkretnych sytuacjach .

  • > : Kieruje wyjście polecenia do pliku.

    command > out.txt

    Powyższe spowoduje zapisanie wyniku commandjako out.txt. Jeśli plik istnieje, jego zawartość zostanie zastąpiona, a jeśli nie istnieje, zostanie utworzony.

    Ten operator jest również często używany do wyboru, czy coś ma zostać wydrukowane na standardowy błąd, czy na standardowe wyjście :

    command >out.txt 2>error.txt

    W powyższym przykładzie >przekieruje standardowe wyjście i 2>przekieruje standardowy błąd. Dane wyjściowe można również przekierowywać za pomocą, 1>ale ponieważ jest to ustawienie domyślne, 1zwykle jest pomijane i zapisywane po prostu jako >.

    Tak więc, aby uruchomić commandna file.txti zapisać jego wyjście w out.txtoraz wszelkie komunikaty o błędach w error.txtjakich można uruchomić:

    command < file.txt > out.txt 2> error.txt
  • >|: Robi to samo co >, ale zastąpi cel, nawet jeśli powłoka została skonfigurowana tak, aby odmawiać zastępowania (za pomocą set -Club set -o noclobber).

    command >| out.txt

    Jeśli out.txtistnieje, wynik commandzastąpi jego zawartość. Jeśli nie istnieje, zostanie utworzony.

  • >>: Robi to samo >, z tym wyjątkiem, że jeśli plik docelowy istnieje, nowe dane są dodawane.

    command >> out.txt

    Jeśli out.txtistnieje, wynik commandzostanie dołączony do niego, po tym, co już w nim jest. Jeśli nie istnieje, zostanie utworzony.

  • &>, >&, >>&I &>>: (bez standardowego). Przekieruj zarówno standardowy błąd, jak i standardowe wyjście, odpowiednio zamieniając lub dołączając.

    command &> out.txt

    Zarówno standardowy błąd, jak i standardowe wyjście commandzostaną zapisane out.txt, nadpisując jego zawartość lub tworząc, jeśli nie istnieje.

    command &>> out.txt

    Jak wyżej, z tym wyjątkiem, że jeśli out.txtistnieje, to wynik i błąd commandzostaną do niego dołączone.

    &>Wariant pochodzi bash, natomiast >&wariant pochodzi z csh (lat wcześniej). Oba są w konflikcie z innymi operatorami powłok POSIX i nie powinny być używane w przenośnych shskryptach.

  • <<: Dokument tutaj. Jest często używany do drukowania ciągów wieloliniowych.

     command << WORD
         Text
     WORD

    Tutaj commandzajmie wszystko, dopóki nie znajdzie następnego wystąpienia WORD, Textw powyższym przykładzie, jako danych wejściowych. Chociaż WORDjest często EoFlub jego odmianami, może być dowolnym ciągiem alfanumerycznym (i nie tylko). Kiedy WORDjest cytowany, tekst w tym dokumencie jest traktowany dosłownie i nie są wykonywane żadne rozwinięcia (na przykład na zmiennych). Jeśli nie jest cytowany, zmienne zostaną rozwinięte. Aby uzyskać więcej informacji, zobacz instrukcję bash .

    Jeśli chcesz potokować wyjście command << WORD ... WORDbezpośrednio do innego polecenia lub poleceń, musisz umieścić potok w tej samej linii, ponieważ << WORDnie możesz umieścić go po słowie kończącym lub w wierszu następującym po nim. Na przykład:

     command << WORD | command2 | command3...
         Text
     WORD
  • <<<: Ciągi tutaj, podobne do dokumentów tutaj, ale przeznaczone dla jednej linii. Istnieją one tylko w porcie Unix lub rc (skąd pochodzi), zsh, niektórych implementacjach ksh, yash i bash.

    command <<< WORD

    Cokolwiek jest podane jako WORDjest rozwinięte, a jego wartość jest przekazywana jako dane wejściowe command. Jest to często używane do przekazywania zawartości zmiennych jako danych wejściowych do polecenia. Na przykład:

     $ foo="bar"
     $ sed 's/a/A/' <<< "$foo"
     bAr
     # as a short-cut for the standard:
     $ printf '%s\n' "$foo" | sed 's/a/A/'
     bAr
     # or
     sed 's/a/A/' << EOF
     $foo
     EOF

Do zamykania lub duplikowania deskryptorów plików można użyć kilku innych operatorów ( >&-, x>&y x<&y). Aby uzyskać szczegółowe informacje na ich temat, zapoznaj się z odpowiednią sekcją podręcznika powłoki ( tutaj na przykład dla bash).

Dotyczy to tylko najpopularniejszych operatorów powłok podobnych do Bourne'a. Niektóre powłoki mają kilka dodatkowych operatorów przekierowań.

Ksh, bash i zsh również mają konstrukcje <(…), >(…)i =(…)(ten ostatni zshtylko w). Nie są to przekierowania, ale podstawienie procesu .

terdon
źródło
2
Prawdopodobnie warto byłoby zauważyć, że nie wszystkie powłoki są równe, i szczególnie podkreślić cechy specyficzne dla bash.
Greg Hewgill
1
@GregHewgill tak, wyjąłem się z tego, mówiąc, że dyskutuję w odniesieniu do bash. Jest to przygotowywane jako kanoniczne pytania i odpowiedzi, aby zamknąć różne pytania „Co to za dziwne rzeczy robią”, a większość z nich pochodzi od użytkowników bash. Mam nadzieję, że ktoś inny przyłączy się i odpowie za pociski bez basha, ale wyróżnienie tych specyficznych dla basha ma sens. Muszę jednak sprawdzić, nie wiem, które są z mojej głowy.
terdon
&>, >>>i <<<wszystkie nie są posiksami, podobnie jak odwołanie do nie tylko znaków innych niż alfanum w nazwie tutaj-doc. Ta odpowiedź również bardzo mało mówi o tym , jak działają - na przykład, rozmowa o prostej komendzie i komendzie jest prawie bezużyteczna bez wyjaśnienia, co to jest i jak decyduje powłoka.
mikeserv
@mikeserv dziękuję. Działają jednak na bash i zsh. Nie wiem, co jest naprawdę specyficzne dla bash na tej liście. Powinienem przejść przez to i dodać powłoki, w których każdy działa, ale to wymagałoby najpierw sprawdzenia.
terdon
1
@ Arc676 Nie, nie oceniają na prawda lub fałsz, to zupełnie inny kontekst. Oznacza to po prostu, że wartość wyjścia różna od 0 oznacza problem (nie false), a kod wyjścia 0 oznacza sukces (nie true). Zawsze tak było i jest dość standardowe. Kod wyjścia inny niż 0 oznacza błąd w każdym znanym środowisku.
terdon
60

Ostrzeżenie dotyczące „>”

Początkujący w systemie Unix, którzy właśnie dowiedzieli się o przekierowaniu wejścia / wyjścia ( <i >) często próbują takich rzeczy

polecenieplik_wejściowy > plik_same

lub

polecenie … < plik      > plik_pliku

lub prawie równoważnie

plik kota | polecenie …> plik_same

( grep, sed, cut, sort, I spellsą przykłady poleceń, które ludzie będą skłonni do stosowania w konstrukcjach takich jak te.) Użytkownicy są zaskoczeni odkryciem, że te scenariusze spowodować pliku staje się pusta.

Niuans, który wydaje się nie wymieniony w drugiej odpowiedzi, znajduje się w pierwszym zdaniu sekcji Przekierowanie bash (1) :

Przed wykonaniem polecenia jego dane wejściowe i wyjściowe mogą zostać przekierowane przy użyciu specjalnej notacji interpretowanej przez powłokę.

Pierwsze pięć słów powinno być pogrubione, pochylone, podkreślone, powiększone, migające, w kolorze czerwonym i oznaczone wykrzyknik w czerwonym trójkącieikoną, aby podkreślić fakt, że powłoka dokonuje żądanych przekierowań przed wykonaniem polecenia . I pamiętaj również

Przekierowanie danych wyjściowych powoduje otwarcie pliku… do zapisu…. Jeśli plik nie istnieje, jest tworzony; jeśli istnieje, jest obcinany do zera.

  1. W tym przykładzie:

    sort roster > roster

    powłoka otwiera rosterplik do zapisu, obcinając go (tzn. usuwając całą jego zawartość), zanim sortprogram zacznie działać. Oczywiście nic nie można zrobić, aby odzyskać dane.

  2. Naiwnie można się tego spodziewać

    tr "[:upper:]" "[:lower:]" < poem > poem

    może być lepiej. Ponieważ powłoka obsługuje przekierowania od lewej do prawej, otwiera się poemdo odczytu (dla trstandardowego wejścia) przed otwarciem do zapisu (dla standardowego wyjścia). Ale to nie pomaga. Mimo że ta sekwencja operacji daje dwa uchwyty plików, oba wskazują ten sam plik. Gdy powłoka otwiera plik do odczytu, zawartość nadal tam jest, ale nadal są blokowane przed uruchomieniem programu. 

Co z tym zrobić?

Rozwiązania obejmują:

  • Sprawdź, czy program, który uruchamiasz, ma swoją własną wewnętrzną możliwość określania, dokąd idzie wyjście. Jest to często wskazywane przez -o(lub --output=) token. W szczególności,

    sort roster -o roster

    jest mniej więcej równoważne z

    sort roster > roster

    z wyjątkiem tego, że w pierwszym przypadku sortprogram otwiera plik wyjściowy. I to na tyle, by nie otworzyć pliku wyjściowego mądry dopiero po to odczytać cały plik (ów) wejściowego.

    Podobnie, przynajmniej niektóre wersje sedmają -i(zmienił i n miejsce) opcji, które mogą być używane do pisania wyjście z powrotem do pliku wejściowego (ponownie, po wszystkie wejścia zostały przeczytane). Redaktorzy lubią ed/ ex, emacs, picoi vi/ vim pozwalają użytkownikowi edytować plik tekstowy i zapisać edytowany tekst w oryginalnym pliku. Pamiętaj, że ed(przynajmniej) można używać w sposób nieinteraktywny.

    • vima powiązaną funkcję. Jeśli wpiszesz , zapisze zawartość bufora edycji , odczyta dane wyjściowe i wstawi do bufora (zastępując oryginalną zawartość).:%!commandEntercommand
  • Proste ale efektywne:

    Komenda ... input_file > temp_file   && mv temp_file  input_file

    Ma to tę wadę, że jeśli input_filejest linkiem, zostanie (prawdopodobnie) zastąpione osobnym plikiem. Ponadto nowy plik będzie własnością użytkownika z domyślnymi zabezpieczeniami. W szczególności niesie to ze sobą ryzyko, że plik będzie czytelny na całym świecie, nawet jeśli oryginał input_filenie był.

    Wariacje:

    • commandinput_file > temp_file && cp temp_file input_file && rm temp_file
      co nadal (potencjalnie) pozostawi temp_fileświat czytelny. Nawet lepiej:
    • cp input_file temp_file && commandtemp_file > input_file && rm temp_file
      Zachowują one status łącza, właściciela i tryb (ochronę) pliku, potencjalnie kosztem dwa razy więcej operacji we / wy. (Może być konieczne użycie opcji podobnej -alub -pwłączonej, cp aby nakazać zachowanie atrybutów).
    • commandinput_file > temp_file &&
      cp --attributes-only --preserve=all input_file temp_file &&
      mv temp_file input_file
      (podzielone na osobne wiersze tylko dla czytelności) To zachowuje tryb pliku (i, jeśli jesteś rootem, właścicielem), ale czyni go własnością użytkownika (jeśli nie jesteś rootem), i czyni go nowym, osobny plik.
  • Ten blog (edycja plików w miejscu) sugeruje i wyjaśnia

    {rm plik_wejściowy   &&   polecenie …> plik_wejściowy ; } < plik_wejściowy

    Wymaga to, aby commandmóc przetwarzać standardowe dane wejściowe (ale prawie wszystkie filtry mogą). Sam blog nazywa to ryzykowną kludge i odradza jego użycie. Spowoduje to również utworzenie nowego, osobnego pliku (niepowiązanego z niczym), będącego własnością użytkownika i posiadającego domyślne uprawnienia.

  • Pakiet moreutils ma polecenie o nazwie sponge:

    polecenieplik_wejściowy | gąbka plik_same

    Zobacz tę odpowiedź, aby uzyskać więcej informacji.

Oto coś, co mnie całkowicie zaskoczyło: syntaxerror mówi :

[Większość tych rozwiązań] zawiedzie w systemie plików tylko do odczytu, gdzie „tylko do odczytu” oznacza, że $HOME będziesz zapisywalny, ale /tmpbędzie tylko do odczytu (domyślnie). Na przykład, jeśli masz Ubuntu i uruchomiłeś konsolę odzyskiwania, często tak jest. Ponadto, operator tutaj, dokument <<<nie będzie działać albo nie, gdyż wymaga /tmpdo odczytu / zapisu , ponieważ będzie to napisać plik tymczasowy w również tam.
(por. to pytanie obejmuje wyjście strace„d”)

W takim przypadku mogą działać następujące elementy:

  • Tylko dla zaawansowanych użytkowników: Jeśli komenda jest gwarantowana do wytworzenia tej samej ilości danych wyjściowych nie ma wejścia (na przykład sort, czy tr bez-d lub -sopcja), można spróbować
    polecenieplik_wejściowy | dd = plik_same_konwek = notrunc
    Zobacz tę odpowiedź i tę odpowiedź, aby uzyskać więcej informacji, w tym wyjaśnienie powyższego, oraz alternatywy, które działają, jeśli twoje polecenie gwarantuje wygenerowanie takiej samej ilości danych wyjściowych, jak jest wejście lub mniej (np. grepLub cut). Te odpowiedzi mają tę zaletę, że nie wymagają żadnej wolnej przestrzeni (lub wymagają bardzo mało). Odpowiedzi powyżej formularza wyraźnie wymagają wystarczającej ilości wolnego miejsca, aby system mógł jednocześnie przechowywać cały (stary) plik i wyjściowy (nowy) plik; nie jest to oczywiście prawda w przypadku większości innych rozwiązań (np. i ). Wyjątek: prawdopodobnie będzie wymagał dużej ilości wolnego miejsca, ponieważcommandinput_file > temp_file && …sed -ispongesort … | dd …sort musi odczytać wszystkie dane wejściowe, zanim będzie mógł zapisać dane wyjściowe, i prawdopodobnie buforuje większość, jeśli nie wszystkie, danych w pliku tymczasowym.
  • Tylko dla zaawansowanych użytkowników:
    polecenieplik_wejściowy 1 <> plik_nazwowy
    może być równoważne z ddodpowiedzią powyżej. Składnia otwiera nazwie pliku na deskryptor pliku zarówno dla wejścia i wyjścia , bez obcinania go - rodzaj połączenia i . Uwaga: Niektóre programy (np. I ) mogą odmówić uruchomienia w tym scenariuszu, ponieważ mogą wykryć, że dane wejściowe i wyjściowe są tym samym plikiem. Zobacz tę odpowiedź w celu omówienia powyższego oraz skrypt, który sprawia, że ​​ta odpowiedź działa, jeśli twoje polecenie gwarantuje wygenerowanie takiej samej ilości danych wyjściowych, jak jest ona wprowadzona lub mniejsza . Ostrzeżenie: nie testowałem skryptu Petera, więc nie rękojmię za to.n<> filen n<n>catgrep

Więc jakie było pytanie?

To był popularny temat na U&L; jest rozwiązany w następujących pytaniach:

… A to nie liczy Super User ani Ask Ubuntu. W tej odpowiedzi umieściłem wiele informacji z odpowiedzi na powyższe pytania, ale nie wszystkie. (Tj., Aby uzyskać więcej informacji, przeczytaj wyżej wymienione pytania i ich odpowiedzi).

PS Nie mam żadnego powiązania z blogiem, który cytowałem powyżej.

Scott
źródło
Ponieważ wciąż pojawia się to pytanie, pomyślałem, że spróbuję napisać „odpowiedź kanoniczną”. Czy powinienem opublikować go tutaj (a może link do niego z niektórych innych pytań o większym natężeniu handlu), czy powinienem przenieść go do jednego z pytań, które faktycznie powodują ten problem? Ponadto, czy może to być sytuacja, w której pytania powinny się łączyć?
Scott,
/ tmp Katalog udostępniony aplikacjom, które potrzebują miejsca do tworzenia plików tymczasowych. Aplikacje będą mogły tworzyć pliki w tym katalogu, ale nie będą zakładały, że takie pliki są zachowywane między wywołaniami aplikacji.
mikeserv
@mikeserv: Tak, (1) cytuję składnię, i (2) powiedziałem, że jestem zaskoczony. Pomyślałem, że jeśli cokolwiek będzie czytać-pisać, to tak będzie /tmp.
Scott,
Cóż, rzecz, którą powiedział @syntaxerror, jest podwójnie dziwna, ponieważ, jak myślę, dashbyłaby domyślną powłoką odzyskiwania w Ubuntu i nie tylko nie rozumie <<<ciągów znaków, ale także otrzymuje anonimowe potoki dla dokumentów <<hered i nie robi z ${TMPDIR:-/tmp}tym bałaganu cel w ogóle. Zobacz to lub to, aby zobaczyć dema dotyczące obsługi dokumentów tutaj. Także dlaczego ta sama ilość wyników lub mniej ostrzeżeń?
mikeserv
@ mikeserv: Cóż, dd … conv=notrunci 1<>odpowiedzi nigdy nie obcinają pliku wyjściowego, więc jeśli wynik polecenia jest mniejszy niż wejście (np. grep), na końcu pliku pozostaną pewne bajty oryginału. I, jeśli wynik jest większy niż na wejściu (na przykład cat -n, nllub (potencjalnie) grep -n), istnieje ryzyko nadpisania starych danych przed już ją przeczytać.
Scott
29

Więcej na obserwacje ;, &, (i)

  • Zauważ, że niektóre polecenia w odpowiedzi terdona mogą być puste. Na przykład możesz powiedzieć

    command1 ;

    (bez command2). Jest to równoważne z

    command1

    (tzn. po prostu działa command1na pierwszym planie i czeka na zakończenie. Porównywalnie,

    command1 &

    (bez command2) uruchomi się command1w tle, a następnie natychmiast wyda kolejny monit powłoki.

  • Natomiast command1 &&, command1 ||i command1 |nie ma sensu. Jeśli wpiszesz jeden z nich, powłoka (prawdopodobnie) przyjmie, że polecenie jest kontynuowane w innej linii. Wyświetli monit wtórnej powłoki (kontynuacja), który jest zwykle ustawiony na >i kontynuuje czytanie. W skrypcie powłoki po prostu odczytuje następny wiersz i dołącza go do tego, co już przeczytał. (Uwaga: to może nie być to, co chcesz się wydarzyć).

    Uwaga: niektóre wersje niektórych powłok mogą traktować takie niekompletne polecenia jak błędy. W takich przypadkach (lub w rzeczywistości, w każdym przypadku, gdy masz długi polecenie), można wprowadzić odwrotny ukośnik ( \) na końcu linii, aby powiedzieć skorupę dalej czytać polecenia na innym wierszu:

    command1  &&  \
    command2

    lub

    find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \
                            -newer some_existing_file -user fred -readable -print
  • Jak terdon mówi, (i )może być stosowany do poleceń grupowych. Stwierdzenie, że „nie są tak naprawdę istotne” w tej dyskusji, jest dyskusyjne. Niektóre polecenia w odpowiedzi Terdona mogą być grupami poleceń . Na przykład,

    ( command1 ; command2 )  &&  ( command3; command4 )

    robi to:

    • Uruchom command1i poczekaj na zakończenie.
    • Następnie, niezależnie od wyniku uruchomienia tego pierwszego polecenia, uruchom command2i poczekaj, aż zakończy się.
    • Jeśli się command2powiedzie,

      • Uruchom command3i poczekaj na zakończenie.
      • Następnie, niezależnie od wyniku uruchomienia tego polecenia, uruchom command4i poczekaj, aż zakończy się.

      Jeśli się command2nie powiedzie, przerwij przetwarzanie wiersza polecenia.

  • Poza nawiasami |wiąże się bardzo mocno, więc

    command1 | command2 || command3

    jest równa

    ( command1 | command2 )  ||  command3

    i &&i ||wiążą się mocniej niż ;tak

    command1 && command2 ; command3

    jest równa

    ( command1 && command2 ) ;  command3

    tzn. command3będą wykonywane niezależnie od statusu wyjścia command1i / lub command2.

G-Man
źródło
Idealnie, +1! Powiedziałem, że nie mają one znaczenia, ponieważ nie chciałem wchodzić w takie szczegóły. Chciałem znaleźć odpowiedź, która mogłaby działać jako szybki ściągawka dla początkujących, którzy zastanawiają się, co to za dziwne dziwactwa na końcu różnych poleceń. Nie chciałem sugerować, że nie są użyteczne. Dzięki za dodanie tego wszystkiego.
terdon
1
Niepokoi mnie problem „masy krytycznej” - jeśli opublikujemy wszystko , co moglibyśmy powiedzieć o powłokach, skończymy z naszą własną wersją Podręcznika referencyjnego Bash TL; DR .
G-Man,
Warto również wspomnieć: W przeciwieństwie do języków rodziny C, ;sam (lub bez poprzedzającego go polecenia) jest błędem składniowym, a nie pustą instrukcją. To ; ;jest błąd. (Często spotykana pułapka dla nowych użytkowników, IMHO). Ponadto: ;;jest specjalnym ogranicznikiem dla caseinstrukcji.
muru
1
@muru: Dobra uwaga, ale uogólnijmy to. Wszelkie operatorów kontrolnych, które mogą się pojawić pomiędzy poleceniami: ;, &&, ||, &, i |, jeśli są błędy pojawiają się z niczym je poprzedzających. Terdon zwrócił się ;;(krótko) w swojej odpowiedzi.
G-Man,
1
@Wildcard: OK, widzę, skąd pochodzisz. Kluczowym słowem jest „maj”; wszystko co powiedziałem to to, że nie gwarantuję, że wszystkie powłoki zaakceptują takie konstrukcje (tj. YMMV). Oczywiście napisałem to, zanim dowiedziałem się o użyciu linebreaktokena w gramatyce powłoki POSIX. Być może więc można śmiało powiedzieć, że wszystkie powłoki zgodne z POSIX je zaakceptują. Podtrzymuję moje oświadczenie jako ogólne wyłączenie odpowiedzialności; jeśli znajdziesz wystarczająco starą powłokę sprzed POSIX, taką jak rzeczywista powłoka Bourne'a lub starsza, wszystkie zakłady są wyłączone.
G-Man