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, iffoozakończy się pomyślnie, a następniebarnie powiedzie się,bazzostanie 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..elsejest 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/[.returnstatusy, a nie wartości logiczne, gdziereturn 0oznacza sukces.