Wydaje się, że oba sygnalizują BASH rozpoczęcie kolejnego polecenia po symbolach, ale czy istnieje wyraźna różnica?
Wydaje się, że oba sygnalizują BASH rozpoczęcie kolejnego polecenia po symbolach, ale czy istnieje wyraźna różnica?
Odpowiedzi:
Dzięki tej linii:
command1 && command2
polecenie 2 zostanie wykonane, jeśli (i tylko wtedy) polecenie 1 zwróci status wyjścia zero, natomiast w tym wierszu:
command1 ; command2
zarówno polecenie1, jak i polecenie2 zostaną wykonane niezależnie. Średnik umożliwia wpisanie wielu poleceń w jednym wierszu.
Możesz wypróbować różnicę dla siebie:
ls /invalid/path && echo "hello!"
ponieważ / nieprawidłowa / ścieżka nie istnieje, ls nie może wyświetlić listy katalogów. Nie powiedzie się komunikat o błędzie: „ls: / invalid / path: Brak takiego pliku lub katalogu”. Druga połowa polecenia (echo „Hello!”) Jest nigdy jeszcze stracony , ponieważ pierwsza połowa nie powiodło się.
ls /invalid/path ; echo "hello!"
Ten sam komunikat o błędzie pojawia się jak poprzednio, ale tym razem druga część jest wykonywana !
ls: / invalid / path:
Witaj w takim pliku lub katalogu !
Dlaczego to jest przydatne?
Załóżmy, że chcesz wyodrębnić plik o nazwie archive.tar.gz
Możesz użyć polecenia tar zxvf archive.tar.gz && rm archive.tar.gz
.
Jeśli z jakiegoś powodu rozpakowanie archiwum nie powiedzie się, druga część nie zostanie wykonana! Możesz spróbować jeszcze raz.
Jeśli użyjesz ; w tej samej sytuacji archiwum jest usuwane i nie można spróbować ponownie.
&&
oznacza AND
, że drugie polecenie zostanie wykonane tylko wtedy, gdy pierwsze zwróci prawdę (bez błędów).
AND
wykonaniu drugi parametr staje się nieistotny, jeśli pierwszy jest równy, false
a zatem kod bazowy zostaje zoptymalizowany w celu odroczenia oceny drugiego parametru, dopóki nie dowie się, jaki jest pierwszy.
&&
jest tylko operatorem binarnym, funkcją. Jedyną „specjalną” rzeczą jest to, że jest to notacja infiksowa (która i tak jest standardem dla większości tego rodzaju operatorów) i opóźnione wykonanie drugiego operandu. Że opóźnia wykonanie rzeczywiście daje mu zdolność do wykorzystania jako coś, co może być postrzegane jako koncepcyjnie if
oświadczenia w tym kontekście , ale nie zabrać z faktu, że to pierwotnie zamierzonego użycia jest w zasięgu warunkowego o rzeczywistej if
oświadczenia. Użycie tutaj jest bardziej „hackowaniem”.
a && b || c = (a && b) || c
. Prosta kolejność oceny. Naprawdę nie ma w tym żadnej tajemnicy. Gdybyś napisał je jak typowe funkcje, po prostu wyglądałoby or(and(a, b), c)
. Ta logika jest taka sama zarówno w if
warunkowym, jak i podczas wprowadzania jej bezpośrednio do wiersza poleceń, ponieważ &&
i ||
są operatorami , biorą dwa operandy i zwracają inny.
Aktualizacja : Dodałem jako skrypt, aby wyróżnić niektóre z możliwych pułapek:
Ponieważ nikt inny nie wspomniał o „||”, zrobię to
Aktualizacja 2 : niektóre ważne przeredagowanie tutaj
&& jest jak „wtedy” wyrażenia „jeśli”, które odpowiada „prawda”
|| NIE jest jak „else” w stwierdzeniu „if”.
|| jest jak „wtedy” wyrażenia „jeśli”, które odpowiada na „fałsz”
Dokładniej, && testuje $? zwraca wartość poprzednio ostatnio wykonanej instrukcji i przekazuje kontrolę do instrukcji lub podpowłoki bezpośrednio po && ... przekazuje kontrolę tylko, jeśli $? jest prawdziwy.
|| jest podobny i często widuje się po instrukcji &&, ale testuje ona na fałszywą wartość zwracaną ($?) z poprzednio ostatnio wykonanej instrukcji ... Uwaga! , Nota Bene! Uwaga: jeśli poprzednia instrukcja jest instrukcją &&, która ponownie sprawdza fałsz, gdy spodziewasz się, że jest to prawda, to || zareaguje na fałsz, więc mieszanie obu na tej samej linii może być ryzykowne
Głównym punktem, który próbuję zrobić, jest błąd, który popełniłem. tj .:
## [[warunek]] i&A || B
jest nie nie zachowuje się jak C / C ++ stylu trójskładnikowego. tj .:
// (warunek)? Odp .: B
Zobacz poniższy skrypt, aby zobaczyć przykłady „nieoczekiwanych” wyników z „A”
Test podstawowy oraz && i || instrukcja musi znajdować się w tym samym wierszu ...
Uruchom ten skrypt, aby zobaczyć, co może się nie powieść podczas używania && i || Ostatnio wykonywane oświadczenie nie może być jeden oczekujesz ..
[[warunek]] && echo Hello || echo Pożegnanie .... jest zwykle bezpieczne,
ponieważ dobrze uformowane echo zwróci prawdę.
ale co z dostępem do pliku, który nie wychodzi?
#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo ======
((1==1)) && echo " ((1==1)) rc=$? ..&&.. condition is true" || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && echo " \$0 0 rc=$? ..&&.. condition is true" || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && echo " \$0 1 rc=$? ..&&.. condition is true" || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo ======
((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false"
$0 0 || echo " \$0 0 rc=$? ..||.. condition is true" && echo " \$0 0 rc=$? ..&&.. condition is false"
((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false"
$0 1 || echo " \$0 1 rc=$? ..||.. condition is true" && echo " \$0 1 rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
exit
próbować
false && echo „hello”
i
fałszywe ; echo „cześć”
Zobacz różnicę
Polecenie (funkcja, w przypadku skryptu) po &&
jest wykonywane w zależności od parametru RETVAL pierwszego polecenia (funkcja, w przypadku skryptu). Zmusza pierwsze polecenie do zwrócenia wartości 0, jeśli zakończy się powodzeniem. Możemy sprawdzić wartość zwracaną, aby wykonać dalsze polecenia.