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 :,varpozostaje ustawione navaluepo:, 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.