stavo sfogliando un file /etc/rc.d/init.d/sendmail
(so che non viene quasi mai utilizzato, ma io “m studiando per un esame), e sono diventato un po confuso riguardo agli operatori &&
e ||
. Ho letto dove possono essere usati in affermazioni come:
if [ test1 ] && [ test2 ]; then echo "both tests are true" elif [ test1 ] || [ test2 ]; then echo "one test is true" fi
Tuttavia, questo script mostra istruzioni a riga singola come:
[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE" [ -f /usr/sbin/sendmail ] || exit 0
Sembra che utilizzino gli operatori &&
e ||
per suscitare risposte basate su test, ma non sono riuscito a trovare la documentazione relativa a questo uso particolare di questi operatori. Qualcuno può spiegare cosa fanno in questo particolare contesto?
Rispondi
Il lato destro di &&
verrà valutato solo se lo stato di uscita del lato sinistro è zero (cioè vero). ||
è lopposto: valuterà il lato destro solo se lo stato di uscita del lato sinistro è diverso da zero (cioè falso).
Puoi considerare [ ... ]
per essere un programma con un valore di ritorno. Se il test allinterno restituisce vero, restituisce zero; altrimenti restituisce un valore diverso da zero.
Esempi:
$ false && echo howdy! $ true && echo howdy! howdy! $ true || echo howdy! $ false || echo howdy! howdy!
Note aggiuntive:
Se lo fai which [
, potresti vedere che [
punta effettivamente a un programma! Di solito non è effettivamente quello che viene eseguito negli script, tuttavia; esegui type [
per vedere cosa viene effettivamente eseguito. Se vuoi provare a utilizzare il programma, specifica il percorso completo come quindi: /bin/[ 1 = 1
.
Commenti
Risposta
Ecco il mio cheat sheet:
- “A; B “Esegui A e poi B, indipendentemente dal successo di A
- ” A & & B “Esegui B se A è riuscito
- “A || B “Esegui B se A non è riuscito
- ” A & “Esegui A in background.
Commenti
- Ci sono ‘ alcuni interessanti paralleli lambda calculus in corso qui dimostrati nel funzionamento di JavaScript (definire le variabili in ordine); ” sinistra (noto anche come true) “:
(a => b => a)
. ” right (aka false) “:(a => b => b)
. ” A; B ” ” quindi ”(a => b => (() => b())(a()))
. ” A & & B ” ” se senza altro (quando) ”(a => b => a()(() => right)(b))
.” A || B ” ” else senza if (a meno che) ”(a => b => a()(b)(() => right))
. ” a & & b || c ” ” ifThenElse ”(a => b => c => (unless(when(a)(b))(c))())
. - nota che in bash, la sinistra è analoga a 0 / stringa vuota, la destra analoga è tutto il resto.
- Che ne dici di una singola barra verticale?
Risposta
per espandere la risposta di @ Shawn-j-Goff “dallalto, &&
è un AND logico e ||
è un OR logico.
Vedi questa parte del Guida avanzata allo scripting di Bash. Alcuni dei contenuti del collegamento per riferimento utente come di seguito.
& & 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.
|| OPPURE
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.
Risposta
Dalla mia esperienza utilizzo & & d || per ridurre unistruzione if a una singola riga.
Supponiamo che stiamo cercando un file chiamato /root/Sample.txt allora literazione tradizionale sarebbe la seguente nella shell:
if [ -f /root/Sample.txt ] then echo "file found" else echo "file not found" fi
Queste 6 righe possono essere ridotte a una singola riga:
[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"
Quando si eseguono alcune iterazioni per impostare variabili o per creare file ecc., la vita è più facile e lo script sembra più fluido usando la funzione if a riga singola, lunico inconveniente è che diventa un po più difficile implementare più comandi da una singola iterazione, tuttavia puoi usare le funzioni.
Commenti
- È interessante. Mi ricorda il codice objc (a == b)? val = 1: val = 2;
- Come posso utilizzare questo comando quando voglio eseguire un processo in background con ” & “? Ricevo un errore di sintassi per
./someScript.sh & && echo 'ok' || echo 'ko'
- nel formato:
foo && bar || baz
, sefoo
riesce quindibar
fallisce, verrà eseguitobaz
, quindi è leggermente diverso da unif
istruzione. - Devo notare che è possibile eseguire più comandi di seguito tra
{}
parentesi, utilizzando&&
o||
, ad esempio:pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }
. Vale anche la pena ricordare cheif..then..else
è un ” riconoscimento ” più affidabile di true / condizioni false rispetto allutilizzo di&&
e||
.
Risposta
Esiste una nozione di “scorciatoia”.
Quando viene valutato (expr1 && expr2)
– expr2
viene valutato solo se exp1
restituisce” true “. Questo perché sia expr1
E expr2
devono essere veri affinché (expr1 && expr2)
sia vero. Se expr1
restituisce “false” expr2
NON viene valutato (scorciatoia) perché (expr1 && expr2)
è già “flase”.
Prova quanto segue: presumi che il file F1
esista & file F2
non esiste:
( [ -s F1 ] && echo "File Exists" ) # will print "File Exists" - no short cut ( [ -s F2 ] && echo "File Exists" ) # will NOT print "File Exists" - short cut
Allo stesso modo per ||
(o) – ma breve il taglio è invertito.
Commenti
- La logica viene solitamente chiamata ” cortocircuito “. ‘ non ho mai visto la frase ” scorciatoia ” utilizzata. Lo menziono per aiutare a trovare riferimenti.
Risposta
Gli esempi nella risposta di Shawn J. Goff sono corrette, ma la spiegazione è il contrario. Controlla:
Il lato destro di & & verrà valutato solo se lo stato di uscita del lato sinistro è NONZERO. || è lopposto: valuterà il lato destro solo se lo stato di uscita del lato sinistro è ZERO.
Commenti
- Sei consapevole che per le shell zero il codice di uscita restituisce vero e quindi il codice di uscita diverso da zero sul lato sinistro di
&&
fa sì che lintera espressione restituisca false ? - Qualcuno non ha approvato le tue modifiche perché non era la tua risposta.Se pensi che una risposta sia sbagliata dovresti votarla negativamente ed eventualmente lasciare un commento; se pensi che sia necessaria una modifica, dovresti lasciare un commento. La modifica serve per correggere errori di grammatica, formattazione e ortografia che non cambiano il significato della risposta.
- @countermode I ‘ scusa, hai ragione, Ho pensato che in Linux zero = falso e diverso da zero = vero (come in C e molti altri linguaggi / ambienti / piattaforme). Mi scuso per il malinteso.
[ ... ]
come programma “, in molti casi è . ‘ è comunemente nel file/bin/[
o/usr/bin/[
.return
stati, non booleani, dovereturn 0
significa successo.