2014-04-27 12 views
13

Sto tentando di eseguire un blocco di codice se un flag è impostato su true e l'altro su false. cioèTest Boolean Bash

var1=true 
var2=false 
if [[ $var1 && ! $var2 ]]; then var2="something"; fi 

Dal momento che non ha valutato il modo in cui mi aspettavo ho scritto diversi altri casi di test e sto avendo difficoltà a capire come sono in corso di valutazione.

aa=true 
bb=false 
cc="python" 
if [[ "$aa" ]]; then echo "Test0" ; fi 
if [[ "$bb" ]]; then echo "Test0.1" ; fi 
if [[ !"$aa" ]]; then echo "Test0.2" ; fi 
if [[ ! "$aa" ]]; then echo "Test0.3" ; fi 
if [[ "$aa" && ! "$bb" ]]; then echo "Test1" ; fi 
if [[ "$aa" && ! "$aa" ]]; then echo "Test2" ; fi 
if [[ "$aa" ]] && ! [[ "$bb" ]]; then echo "test3" ; fi 
if [[ "$aa" ]] && ! [[ "$cc" ]]; then echo "test4" ; fi 
if [[ $aa && ! $bb ]]; then echo "Test5" ; fi 
if [[ $aa && ! $aa ]]; then echo "Test6" ; fi 
if [[ $aa ]] && ! [[ $bb ]]; then echo "test7" ; fi 
if [[ $aa ]] && ! [[ $cc ]]; then echo "test8" ; fi 

Quando eseguo precedente codeblock l'unico output che ottengo è

Test0
Test0.1
Test0.2

tuttavia, la mia aspettativa è che vorrei get

Tes t0
Test1
Test3
Test5
Test7

ho cercato di capire il modo migliore per eseguire test simili, tuttavia maggior parte degli esempi che ho trovato sono impostati nel formato
se [[ "$ aa" == true]];
che non è proprio quello che voglio fare. Quindi la mia domanda è qual è il modo migliore per fare paragoni come questo, e perché alcuni dei casi di test che mi aspetterei di passare semplicemente no?

Grazie!

risposta

14

Senza alcun operatore, [[ controlla solo se la variabile è vuota. Se lo è, allora è considerato falso, altrimenti è considerato vero. Il contenuto delle variabili non ha importanza.

+0

Grazie. Dopo aver commentato la riga 'bb = false' e ​​poi riascoltare la sceneggiatura, vedo come funziona, mi ha dato un risultato più in linea con quello che mi aspettavo. – JLMarks

+0

Per inciso, questa è la seconda domanda che ho mai posto su StackOverflow, il primo è [oltre due anni fa] (http://stackoverflow.com/questions/9170155/is-there-a-simple-to-to split-e-ricongiungersi-a-tarfile-con-python). In quella domanda tu dove l'unico utente a rispondermi. Sono appena arrivato ad accettare la tua risposta, quindi grazie! – JLMarks

+0

Contento di aver potuto aiutare. –

14

La tua comprensione dei valori booleani nel contesto della shell non è corretta.

var1=true 
var2=false 

Entrambe queste variabili sono vero poiché questi sono non vuota stringhe.

Si potrebbe invece fare uso di contesto aritmetica:

$ a=1 
$ b=0 
$ ((a==1 && b==0)) && echo y 
y 
$ ((a==0 && b==0)) && echo y 
$ 
$ ((a && !(b))) && echo y;  # This seems to be analogous to what you were attempting 
y 
+1

Si può combinare con 'readonly true = 1 yes = 1 no = 0 false = 0' per creare costanti affidabili per' true' e 'false' all'interno di espressioni aritmetiche. –

4

La shell non ha variabili booleane, di per sé.Tuttavia, vi sono i comandi denominati true e false i cui stati di uscita sono 0 e 1, rispettivamente, e quindi possono essere utilizzati in modo simile ai valori booleani.

var1=true 
var2=false 
if $var1 && ! $var2; then var2="something"; fi 

La differenza è che invece di test, se var1 è impostato su un valore vero, si espande al nome di un comando, che corre e riesce. Allo stesso modo, var2 viene espanso in un nome di comando che viene eseguito e non riesce, ma poiché è prefisso con !, lo stato di uscita viene invertito per indicare il successo.

(Si noti che a differenza della maggior parte dei linguaggi di programmazione, uno stato di uscita di 0 indica il successo perché mentre la maggior parte dei comandi ha 1 modo per avere successo, ci sono molti modi in cui possono fallire, quindi valori diversi diversi da zero possono essere assegnati a significati diversi.)

0

Il più vicino possibile può essere utilizzare le funzioni anziché le variabili perché è possibile utilizzare il loro stato di ritorno in condizionali.

$ var1() { return 0; } 
$ var2() { return 1; } # !0 = failure ~ false 

e siamo in grado di testare in questo modo

$ var1 && echo "it's true" || echo "it's false" 
it's true 
$ var2 && echo "it's true" || echo "it's false" 
it's false 

o questo modo

$ if var1; then echo "it's true"; else echo "it's false"; fi 
it's true 
$ if var2; then echo "it's true"; else echo "it's false"; fi 
it's false 

Spero che questo aiuti.

+0

Vedere @chepner sopra: http://stackoverflow.com/a/23324368/1246494 le funzioni true/false sono incorporate per agire come valori booleani. – Bradmage