Przeglądałem plik /etc/rc.d/init.d/sendmail
(wiem, że jest to rzadko używane, ale ja „m przygotowuję się do egzaminu) i „trochę się pogubiłem co do operatorów &&
i ||
. Czytałem już, gdzie można ich używać w instrukcjach, takich jak:
if [ test1 ] && [ test2 ]; then echo "both tests are true" elif [ test1 ] || [ test2 ]; then echo "one test is true" fi
Jednak ten skrypt pokazuje instrukcje jednowierszowe, takie jak:
[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE" [ -f /usr/sbin/sendmail ] || exit 0
Wydaje się, że używają operatorów &&
i ||
w celu uzyskania odpowiedzi na podstawie testy, ale nie byłem w stanie znaleźć dokumentacji dotyczącej tego konkretnego zastosowania tych operatorów. Czy ktoś może wyjaśnić, co to robi w tym konkretnym kontekście?
Odpowiedź
Prawa strona &&
zostanie sprawdzone tylko wtedy, gdy kod zakończenia po lewej stronie wynosi zero (tj. prawda). ||
jest odwrotnie: obliczy prawą stronę tylko wtedy, gdy status wyjścia po lewej stronie jest różny od zera (tj. fałsz).
Możesz rozważyć [ ... ]
jako program ze zwracaną wartością. Jeśli test wewnętrzny ma wartość true, zwraca zero; w przeciwnym razie zwraca wartość różną od zera.
Przykłady:
$ false && echo howdy! $ true && echo howdy! howdy! $ true || echo howdy! $ false || echo howdy! howdy!
Dodatkowe uwagi:
Jeśli zrobisz which [
, możesz zobaczyć, że [
faktycznie wskazuje na program! Zwykle nie jest to jednak ten, który działa w skryptach; uruchom type [
, aby zobaczyć, co faktycznie jest uruchamiane. Jeśli chcesz spróbować użyć programu, podaj pełną ścieżkę, np. więc: /bin/[ 1 = 1
.
Komentarze
Odpowiedź
Oto moja ściągawka:
- „A; B „Uruchom A, a następnie B, niezależnie od powodzenia A
- „ A & & B „B” jeśli A się powiodło
- „A || B „Uruchomienie B, jeśli A nie powiodło się
- „ A & „Uruchomienie A w tle.
Komentarze
- Istnieją ' kilka interesujących paralel z rachunkiem lambda, pokazanych tutaj w działającym JavaScript (zdefiniuj zmienne w kolejności); ” left (aka true) „:
(a => b => a)
. ” right (inaczej false) „:(a => b => b)
. ” A; B ” „, a następnie ”(a => b => (() => b())(a()))
. ” A & & B ” ” jeśli bez else (kiedy) ”(a => b => a()(() => right)(b))
.” A || B ” ” else bez if (chyba że) ”(a => b => a()(b)(() => right))
. ” a & & b || c ” ” ifThenElse ”(a => b => c => (unless(when(a)(b))(c))())
. - zauważ, że w bash lewe to analogiczne 0 / pusty ciąg, prawe analogiczne to wszystko inne.
- A co z pojedynczym pionowym paskiem?
Odpowiedz
aby rozwinąć odpowiedź @ Shawn-j-Goff „z góry, &&
to logiczne ORAZ, a ||
to logiczne LUB.
Zobacz tę część Zaawansowany przewodnik po skryptach Bash. Część zawartości z linku w celach informacyjnych dla użytkownika, jak poniżej.
& & AND
if [ $condition1 ] && [ $condition2 ] # Same as: if [ $condition1 -a $condition2 ] # Returns true if both condition1 and condition2 hold true... if [[ $condition1 && $condition2 ]] # Also works. # Note that && operator not permitted inside brackets #+ of [ ... ] construct.
|| LUB
if [ $condition1 ] || [ $condition2 ] # Same as: if [ $condition1 -o $condition2 ] # Returns true if either condition1 or condition2 holds true... if [[ $condition1 || $condition2 ]] # Also works. # Note that || operator not permitted inside brackets #+ of a [ ... ] construct.
Odpowiedź
Z własnego doświadczenia korzystam & & an d || aby zredukować instrukcję if do jednej linii.
Powiedzmy, że szukamy pliku o nazwie /root/Sample.txt, to tradycyjna iteracja w powłoce wyglądałaby następująco:
if [ -f /root/Sample.txt ] then echo "file found" else echo "file not found" fi
Te 6 wierszy można zredukować do jednej linii:
[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"
Podczas wykonywania kilku iteracji w celu ustawienia zmiennych lub do tworzenia plików itp., życie jest łatwiejsze, a skrypt wygląda lepiej, używając pojedynczej linii if function, jedyną wadą jest to, że implementacja wielu poleceń z jednej iteracji staje się nieco trudniejsza, jednak można korzystać z funkcji.
Komentarze
- To jest fajne. Przypomina mi kod objc (a == b)? val = 1: val = 2;
- Jak mogę użyć tego polecenia, gdy chcę uruchomić proces w tle z ” & „? Otrzymuję błąd składni dla
./someScript.sh & && echo 'ok' || echo 'ko'
- W postaci:
foo && bar || baz
, iffoo
zakończy się pomyślnie, a następniebar
nie powiedzie się,baz
zostanie uruchomiony, więc różni się nieco odif
. - Muszę zauważyć, że możliwe jest wykonanie kilku poleceń z rzędu w nawiasach
{}
, używając&&
lub||
, na przykład:pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }
. Warto również wspomnieć, żeif..then..else
jest bardziej niezawodnym ” narzędziem do rozpoznawania ” typu true / fałszywe warunki niż użycie&&
i||
.
Odpowiedź
Istnieje pojęcie „krótkiego skrawania”.
Podczas oceny (expr1 && expr2)
– expr2
jest oceniane tylko wtedy, gdy exp1
ma wartość„ prawda ”. Dzieje się tak, ponieważ expr1
ORAZ expr2
muszą być prawdziwe, aby (expr1 && expr2)
było prawdziwe. Jeśli expr1
ma wartość „false”, expr2
NIE jest oceniane (skrót), ponieważ (expr1 && expr2)
jest już „flase”.
Załóżmy, że plik F1
istnieje & plik F2
nie istnieje:
( [ -s F1 ] && echo "File Exists" ) # will print "File Exists" - no short cut ( [ -s F2 ] && echo "File Exists" ) # will NOT print "File Exists" - short cut
Podobnie dla ||
(lub) – ale krótkie cięcie jest odwrócone.
Komentarze
- Logika jest zwykle określana jako ” krótkie spięcie „. ' nigdy nie widziałem używanego wyrażenia ” krótkie cięcie „. Wspominam o tym, aby pomóc w znalezieniu odniesień.
Odpowiedź
Przykłady w odpowiedzi Shawna J. Goffa są poprawne, ale wyjaśnienie jest odwrotne. Sprawdź:
Prawa strona & & zostanie oceniony tylko wtedy, gdy status wyjścia po lewej stronie to NONZERO. || jest odwrotnie: ocenia prawą stronę tylko wtedy, gdy status wyjścia po lewej stronie wynosi ZERO.
Komentarze
- Wiesz, że dla powłok zero kod zakończenia zwraca wartość prawda , a zatem niezerowy kod zakończenia po lewej stronie
&&
powoduje, że całe wyrażenie zwraca false ? - Ktoś nie zatwierdził twoich zmian, ponieważ nie była to Twoja odpowiedź.Jeśli uważasz, że jakaś odpowiedź jest niepoprawna, powinieneś ją zlekceważyć i ewentualnie zostawić komentarz; jeśli uważasz, że wymaga zmiany, zostaw komentarz. Edycja służy do poprawiania gramatyki, formatowania i błędów ortograficznych, które nie zmieniają znaczenia odpowiedzi.
- @countermode I ' m przepraszam, masz rację, Myślałem, że w Linuksie zero = false i nonzero = true (jak w C i wielu innych językach / środowiskach / platformach). Przepraszam za nieporozumienie.
[ ... ]
być programem „, w wielu przypadkach jest . Zwykle jest ' w pliku/bin/[
lub/usr/bin/[
.return
statusy, a nie wartości logiczne, gdziereturn 0
oznacza sukces.