Co jest bardziej idiomatyczne w skrypcie basha: `|| true` lub `|| : `?

Nie wykonuję zbyt wielu skryptów powłoki, więc byłem trochę zaskoczony, gdy czytałem dokumentacja git submodule i zobaczyłem składnię, której użyli w tej dokumentacji:

A niezerowy powrót z polecenia w dowolnym module podrzędnym powoduje zakończenie przetwarzania. Można to zmienić, dodając || : na końcu polecenia.

Musiałem sprawdzić, że || : było skrótem do wymuszania pomyślnego zakończenia polecenia. Za każdym razem, gdy musiałem pomyślnie zakończyć polecenie , Użyłem || true. Czy || : jest uważane za bardziej idiomatyczne?

Komentarze

  • It ' warto zauważyć, że ||: (bez spacji) jest również poprawne w bash. Robi to samo, co || : lub || true.

Odpowiedź

true nie został wbudowany w powłokę Bournea. : zawsze tak było (był to sposób wprowadzania komentarzy przed wprowadzeniem #).

To i ponieważ pisanie jest krótsze i jest to prawdopodobnie główny powód, dla którego ludzie wolą : od true.

Zwróć uwagę na kolejną różnicę w Powłoki POSIX (dla bash, tylko w trybie POSIX): podczas gdy true jest zwykłą wbudowaną wersją (nawet nie musi być wbudowana) , : to specjalne wbudowane narzędzie. Ma to kilka konsekwencji, z których większość prawdopodobnie nie będzie miała żadnego wpływu w tym konkretnym przypadku:

  • Jeśli polecenie : nie powiedzie się, w tym z powodu nieudanego przekierowania, które powoduje zamknięcie powłoki. W praktyce to prawdopodobnie nie zrobi różnicy, jeśli nie przekażesz przekierowań do :

    $ sh -c ": > / ; echo HERE" sh: 1: cannot create /: Is a directory $ sh -c "true > /; echo HERE" sh: 1: cannot create /: Is a directory HERE 
  • w var=value :, var pozostaje ustawione na value po :, a nie w przypadku true:

    $ var=1; var=2 : ; echo "$var" 2 $ var=1; var=2 true; echo "$var" 1 

Pamiętaj również, że || true działa w powłokach rc i csh rodzin, ale nie || : (ale nie do anulowania set -e w csh).

|| : to nie to samo co :. Oznacza to lub uruchom : w przeciwnym razie (to znaczy, jeśli poprzedni potok zawiedzie).

set -e false 

Spowodowałoby zamknięcie powłoki z powodu set -e (inaczej opcja errexit) i ma niezerowy (błąd) kod zakończenia. Efekt set -e jest anulowany, jeśli polecenie zwracające niezerowy kod zakończenia jest używane jako warunek , jak w:

if false; then ... while false; do ... false && : ... false || : ... 

false && : anuluje tylko set -e. false || : anuluje efekt set -e i ustawia stan wyjścia na 0, więc jest bardziej idiomatyczny powiedzieć, że chcemy zignorować kod zakończenia błędu polecenia. Większość twierdzi, że || true jest bardziej czytelny (wyraźniej oddaje intencję).

Komentarze

  • && : jest genialny, czy są jakieś dokumenty lub dalsze lektury na ten temat? Google nie daje mi rady znaleźć tego rodzaju słów kluczowych…

Odpowiedź

Większość z tych odpowiedzi zawodzi zająć się najczęstszym użyciem :.

Po pierwsze, ta dyskusja nie dotyczy żadnej powłoki, która nie jest Bourne shell (sh) pochodna. To powiedziawszy, wszystkie powłoki pochodne Bournea postrzegają true i : jako to samo. Zachęcano programistów do używania : zamiast true, ponieważ : jest zawsze wbudowana, choć kiedyś zdarzały się przypadki, w których true nie zawsze było wbudowane.

: ma dwa zastosowania. Nie jest synonimem #, ale ma inną funkcję. Podczas debugowania skryptu w set -x, wiersze, w których używany jest #, są usuwane przez parser i całkowicie ignorowane, natomiast wiersze z : są analizowane i oceniane. Jest to bardzo przydatne w debugowaniu, ponieważ pod -x te wiersze są pokazane, a ich wartość po ocenie jest wyświetlana.Jest to podobne do umieszczania instrukcji print w kodzie, które są wyświetlane tylko w trybie -x. Uważaj na wartości po :, ponieważ są one prawdziwym kodem, a efekty uboczne mogą mieć wpływ na Twój program.

Komentarze

  • Jakie jest drugie użycie?

Odpowiedź

Ogólnie w bashu dwukropek : i true są równoważne.

Is | | : uważany za bardziej idiomatyczny?

Myślę, że jest oparty na kontekście .

Jeśli chcesz, aby return value lub condition było zawsze prawdziwe , powinieneś użyć słowa kluczowego true, dzięki temu kod będzie bardziej przejrzysty i widzowie wiedzą, że chcesz podkreślić wartość true , tj .:

while true; do something 

lub

<commnad> RETURN_VALUE= $? || true 

A jeśli chcesz nic nie robić lub NOP w powłoce należy użyć dwukropka :

if condition then : # DO NOTHING HERE else do something fi 

lub

while conditon do : # DO NOTHING HERE done 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *