Questa domanda ha due parti:
(a) Capire cosa sta facendo il codice tagliato
(b) Comprendere la differenza tra stato di uscita e stato del reso nel contesto di bash
.
Ecco il codice tagliato che sto cercando di capire:
if var=-2 && (( var+=2 ))
then
echo "True"
else
echo "False"
fi
L'esecuzione di questo produce False
. Non riesco a capire perché questo sta accadendo.
Se ho capito bene, ecco cosa potrebbe succedere con il if
condizione:
(a) var=-2
crea lo stato di uscita 0, perché l'assegnazione è riuscita
(b) (( var+=2 ))
aggiunge 2 al valore di var
e l'espressione valuta zero. Quindi lo stato di uscita è 1 per questo termine
(c) 0 &&1 crea uno stato esistente di 0 che viene quindi utilizzato da if
costruire
Il if
costrutto dovrebbe semplicemente controllare lo stato di uscita e quando è zero prende il allora il percorso. Nel passaggio (c) sopra è zero ma lo script accetta ancora altro il percorso. È questo il modo corretto per capirlo?
Inoltre, continuo a vedere vari bash
i testi usano stato di uscita e stato del reso in modo intercambiabile.
Dubito di var=-2
l'assegnazione avrebbe qualsiasi tipo di stato di uscita perché non è un programma. Ma qualsiasi chiarimento sulla differenza tra i due sarà ottimo.
Risposta accettata:
Questo è:
if
first list of commands
then
second list of commands
else
third list of commands
fi
Questo è per eseguire il secondo elenco di comandi se il primo elenco di comandi restituisce un true /successo (zero) stato di uscita, ovvero se l'ultimo comando eseguito ritorna con uno stato di uscita zero.
In:
var=-2 && ((var += 2))
È cmd1 && cmd2
dove cmd2
viene eseguito solo se cmd1
ha successo.
var=-2
In genere avrà successo fintanto che $var
non è stato reso di sola lettura, quindi ((var += 2))
verrà eseguito il comando:
((arithmetic expression))
Restituisce successo /vero purché l'espressione sia valutata correttamente (nessun errore di sintassi) e il risultato dell'espressione sia diverso da zero.
((123))
,((1 + 1))
,((1 == 1))
restituisce vero((0))
,((-2 + 2))
,((2 == -2))
restituisce falso.((4294967296 * 4294967296))
restituisce false nella maggior parte delle shell a causa del wrapping di interi a 64 bit
var += 2
come espressione aritmetica, esegue l'assegnazione e risolve il valore assegnato, qui 0, da cui il falso stato di uscita.
Puoi vedere il valore su cui si basa lo stato di uscita, utilizzando il $((...))
sintassi di espansione aritmetica:
$ echo "$((1 + 1)) $((2 == 2)) $((2 == -2)) $((var = -2)) $((var += 2))"
2 1 0 -2 0
Oppure assegnandolo a una variabile:
$ var=-2; ((result = (var += 2)))
$ echo "$? $result $var"
1 0 0
$?
contiene lo stato di uscita del comando precedente. Per quanto riguarda if
/then
/else
/fi
è interessato, 0 significa vero, qualsiasi altra cosa significa falso.
La confusione qui deriva dal fatto che per le espressioni aritmetiche, è il contrario: significa falso e qualsiasi altra cosa significa vero (ad esempio,
2 == 2
è 1
mentre 2 < 1
è ).
Per evitare di preoccuparti della differenza, dimentica $?
e i suoi possibili valori. Pensa in termini di booleano vero /falso , successo /fallimento .
grep -q foo file
Restituisce vero se foo
si trova in file
.
[ "$a" = "$b" ]
Restituisce vero se $a
contiene la stessa cosa di $b
.
((6 * 3 - 12))
((4 == 1))
Restituisce true se il risultato dell'espressione aritmetica è un numero diverso da zero.
Non importa se quelli veri /falso sono espressi in termini di 0 o 1 dello stato di uscita di quei grep
/[
comandi o ((...))
costruire.