Jag skumade igenom en /etc/rc.d/init.d/sendmail
-fil (jag vet att det nästan aldrig används, men jag ”m studerar för en tentamen) och jag har blivit lite förvirrad över operatörerna &&
och ||
. Jag har läst var de kan användas i uttalanden som:
if [ test1 ] && [ test2 ]; then echo "both tests are true" elif [ test1 ] || [ test2 ]; then echo "one test is true" fi
Detta skript visar emellertid enradiga uttalanden som:
[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE" [ -f /usr/sbin/sendmail ] || exit 0
De verkar använda operatörerna &&
och ||
för att framkalla svar baserat på test, men jag har inte kunnat gräva upp dokumentation om just denna användning av dessa operatörer. Kan någon förklara vad dessa gör i just detta sammanhang?
Svar
Höger sida av &&
utvärderas endast om utgångsstatusen för vänster sida är noll (dvs. sant). ||
är motsatsen: den kommer att utvärdera höger sida endast om statusen för vänster sida är noll (dvs. falsk).
Du kan överväga [ ... ]
för att vara ett program med returvärde. Om testet inuti utvärderas till sant returnerar det noll; det returnerar i annat fall noll.
Exempel:
$ false && echo howdy! $ true && echo howdy! howdy! $ true || echo howdy! $ false || echo howdy! howdy!
Extra anteckningar:
Om du gör which [
, kanske du ser att [
faktiskt pekar på ett program! Det är dock vanligtvis inte det som körs i skript. Kör type [
för att se vad som faktiskt körs. Om du vill försöka använda programmet, ge bara hela vägen som så: /bin/[ 1 = 1
.
Kommentarer
Svar
Här är mitt fuskark:
- ”A; B ”Kör A och sedan B, oavsett framgång för A
- ” A & & B ”Kör B om A lyckades
- ”A || B ”Kör B om A misslyckades
- ” A & ”Kör A i bakgrunden.
Kommentarer
- Det finns ’ några intressanta lambdakalkylparalleller som pågår här i JavaScript som fungerar (definiera variablerna i ordning); ” vänster (aka true) ”:
(a => b => a)
. ” rätt (aka falsk) ”:(a => b => b)
. ” A; B ” ” sedan ”(a => b => (() => b())(a()))
. ” A & & B ” ” om utan annat (när) ”(a => b => a()(() => right)(b))
.” A || B ” ” annat utan om (om inte) ”(a => b => a()(b)(() => right))
. ” a & & b || c ” ” ifThenElse ”(a => b => c => (unless(when(a)(b))(c))())
. - Observera att i bash är vänster analog 0 / tom sträng, höger analog är allt annat.
- Vad sägs om en enda vertikal stapel?
Svar
för att expandera på @ Shawn-j-Goffs svar från ovan, &&
är en logisk AND och ||
är en logisk ELLER.
Se denna del av Advanced Bash Scripting Guide. En del av innehållet från länken för användarreferens enligt nedan.
& & OCH
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.
|| ELLER
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.
Svar
Från min erfarenhet använder jag & & och d || för att minska ett if-uttalande till en enstaka rad.
Säg att vi letar efter en fil som heter /root/Sample.txt, då skulle den traditionella iterationen vara som följer i skal:
if [ -f /root/Sample.txt ] then echo "file found" else echo "file not found" fi
Dessa 6 rader kan reduceras till en enda rad:
[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"
När du kör några iterationer för att ställa in variabler eller för att skapa filer etc., livet är lättare och skriptet ser snyggare ut med funktionen en rad om det är den enda nackdelen att det blir lite svårare att implementera flera kommandon från en enda iteration men du kan använda funktioner.
Kommentarer
- Det här är coolt. Påminner mig om objc-kod (a == b)? val = 1: val = 2;
- Hur kan jag använda det här kommandot när jag vill köra en process i bakgrunden med ” & ”? Jag får ett syntaxfel för
./someScript.sh & && echo 'ok' || echo 'ko'
- I form:
foo && bar || baz
, omfoo
lyckas dåbar
misslyckas,baz
körs, så det skiljer sig subtilt från enif
uttalande. - Jag måste notera att det är möjligt att utföra flera kommandon i rad i
{}
parenteser med&&
eller||
, såsom:pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }
. Det är också värt att nämna attif..then..else
är en mer tillförlitlig ” igenkännare ” av true / falska villkor än att använda&&
och||
.
Svar
Det finns en uppfattning om ”genväg”.
När (expr1 && expr2)
utvärderas – expr2
utvärderas endast om exp1
utvärderas till” true ”. Detta beror på att både expr1
OCH expr2
måste vara sanna för att (expr1 && expr2)
ska vara sant. Om expr1
utvärderas till ”falskt” utvärderas expr2
(genväg) eftersom (expr1 && expr2)
är redan ”flase”.
Prova följande – anta att fil F1
finns & fil F2
finns inte:
( [ -s F1 ] && echo "File Exists" ) # will print "File Exists" - no short cut ( [ -s F2 ] && echo "File Exists" ) # will NOT print "File Exists" - short cut
På samma sätt för ||
(eller) – men kort skärning är omvänd.
Kommentarer
- Logiken kallas vanligtvis ” kortslutning ”. Jag ’ Jag har aldrig sett frasen ” genväg ” används. Jag nämner detta för att hjälpa till med att hitta referenser.
Svar
Exemplen i svaret av Shawn J. Goff är korrekta, men förklaringen är tvärtom. Kontrollera:
Höger sida av & & utvärderas endast om utgångsstatusen till vänster är NONZERO. || är motsatsen: den utvärderar bara höger sida om statusen för vänster sida är NOLL.
Kommentarer
- Du är medveten om att för skal noll utgångskod utvärderas till sant och därmed icke-noll utgångskod till vänster om
&&
resulterar i att hela uttrycket returnerar falskt ? - Någon godkände inte dina ändringar eftersom det inte var ditt svar.Om du tycker att något svar är felaktigt bör du nedrösta det och eventuellt lämna en kommentar; om du tror att det kräver en ändring, bör du lämna en kommentar. Redigering är för att korrigera grammatik, formatering och stavfel som inte ändrar innebörden av svaret.
- @countermode I ’ tyvärr, du har rätt, Jag tänkte i Linux zero = false och nonzero = true (som i C och många andra språk / miljöer / plattformar). Jag ber om ursäkt för missförståndet.
[ ... ]
för att vara ett program ”, i många fall är . Det ’ är vanligt i filen/bin/[
eller/usr/bin/[
.return
statusar, inte booleaner, därreturn 0
betyder framgång.