2011-12-20 12 views
46

Perché bash ha il seguente comportamento?

echo $((true == false)) 
1 

avrei pensato che questo sarebbe stampare 0, ma stampa 1.

Questo è ulteriormente complicato dai seguenti fatti:

> echo $((true)) 
0 
> echo $((false)) 
0 
> echo $((true == true)) 
1 
> echo $((false == false)) 
1 

risposta

56

Tutti i poster che parlano di 0 è vero e 1 falso hanno perso il punto. In questo caso, 1 è vero e 0 è falso nel solito senso booleano a causa del contesto di valutazione aritmetica causato da $(()).

L'operazione == all'interno di $(()) non è l'uguaglianza degli stati di ritorno in Bash, esegue l'uguaglianza numerica utilizzando i valori letterali indicati dove "falso interpretato come 0 in quanto non hanno alcun valore ancora assegnato:

$ echo $((true)) 
0 
$ echo $((false)) 
0 

Se si desidera confrontare lo stato di ritorno del vero e del falso si desidera qualcosa di simile:

true 
TRUE=$? 
false 
FALSE=$? 
if (($TRUE == $FALSE)); then echo TRUE; else echo FALSE; fi 

Ma, io non sono sicuro perché tu vorresti fare t il suo.

MODIFICA: Correggere la parte nella risposta originale su "vero" e "falso" interpretati come stringhe. Non sono. Sono trattati come variabili, ma non hanno ancora alcun valore legato a loro.

+0

Inoltre, 'echo $ (($ TRUE == $ FALSE))' riferirà '0' come ci si aspetterebbe. 'echo $ (($ TRUE == $ TRUE))' e 'echo $ (($ FALSE == $ FALSE))' riporterà anche '1'. – zostay

+0

Questo è corretto. "true" e "false" come booleani non esistono in bash e quindi non hanno un significato speciale all'interno di '$ (())' – Sorpigal

+1

+1 e -1 a tutte le altre risposte ... ha fatto qualcun altro leggi la domanda? – Random832

-2

Perché in bash, 0 è vero e tutto diverso da 0 è falso.

21

OK, quindi, sembra che ci sia molta confusione su ciò che lo fa $((...)).

Fa una valutazione aritmetica dei suoi operandi, bareword sono variabili, non comandi o stringhe (cioè, true è veramente $true), e tutto ciò che non è un numero è 0. L'operatore == confronta due numeri e restituisce 1 se sono uguali.

È per questo $((true == false)) è 1: non c'è true o false variabili di ambiente nell'ambiente, che significa sia $true e $false valutare la stringa vuota, quindi 0 nel contesto aritmetica!

Per essere completa, è possibile utilizzare anche la sostituzione di comando nel contesto aritmetica ... Per esempio:

$ echo $((`echo 2`)) 
2 
$ echo $((3 + $(echo 4))) 
7 
$ a=3 
$ echo $((a + $(echo 4))) 
7 
# undefine a 
$ a= 
$ echo $((a + $(echo 4))) 
4 
$ a="Hello world" 
$ echo $((a + 1)) 
1 
# undefine a again 
$ a= 
$ echo $(($(echo $a))) 
0 
+0

Ho già messo in svantaggio questa risposta perché stai dicendo correttamente la stessa cosa di @zostay, semplicemente non hai capito il suo esempio. Stai ricevendo un errore di sintassi perché TRUE e FALSE non sono stati definiti nella tua shell; il suo esempio completo DID li definisce come i codici numerici di ritorno dei comandi true e false (guarda più da vicino le 4 righe sopra nell'altra risposta; "TRUE = $?" sta definendo la variabile $ TRUE, ecc.) – Izkata

+0

Sono corretto per l'esempio. Ma no, non sto dicendo la stessa cosa: @zostay dice che 'true' e' false' sono trattati come stringhe - questo non è il caso_! Sono trattati come variabili di ambiente, che è una bestia completamente diversa, e '$ true' e' $ false' valutano di svuotare stringhe, non letterali. prova 'echo $ (($ (echo $ a)))' dove 'a' non è definito: non produce un errore di sintassi ma restituisce 0. Dice giustamente, però, che le stringhe valutano a 0. Ma in effetti , tutto ciò che non è un numero, è valutato a 0 in questo contesto. – fge

-1
$ bash --version 
GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13) 
$ true="true" 
$ unset false 
$ if [[ $true ]] ; then echo hi ; fi 
hi 
$ if [[ $false ]] ; then echo hi ; fi 
$ if [[ $true || $false ]] ; then echo hi ; fi 
hi 
$ if [[ $false || $true ]] ; then echo hi ; fi 
hi 
$ if [[ $false && $true ]] ; then echo hi ; fi 
$ if [[ $true && $false ]] ; then echo hi ; fi 
$ if [[ $true == $false ]] ; then echo hi ; fi 
$ if [[ $true == $true ]] ; then echo hi ; fi 
hi 
$ if [[ $false == $false ]] ; then echo hi ; fi 
hi` 
+1

Benvenuti in SO! Qualche spiegazione del tuo codice e del suo output renderebbe la tua risposta molto più utile alle persone. – J0e3gan

+0

Tutto quello che stai facendo è mostrare il codice e qual è il comportamento. Non spieghi ** perché ** questo codice funziona. Il dumping del codice è solitamente disapprovato qui! – rayryeng

Problemi correlati