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
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 navalue
po:
, a nie w przypadkutrue
:$ 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
||:
(bez spacji) jest również poprawne w bash. Robi to samo, co|| :
lub|| true
.