Comprensione degli operatori booleani nello script bash [duplicate]

Questa domanda ha già una risposta qui :

Risposta

La variabile $phone_missing è una stringa che sembra contenere false. E una stringa non vuota restituisce true. Vedi anche http://www.linuxintro.org/wiki/Babe#empty_strings

Commenti

  • Ah, va bene. Avrei dichiarato quella variabile come booleana (almeno non con la parola declare) ma la console di ash ' me lo ha permesso. Inoltre, non ' voglio confrontare le stringhe. Come funziona?
  • stackoverflow.com/questions/2953646/… , ma attenzione: questo tizio ESEGUE una variabile stringa, e tanto falso quanto vero sono i comandi unix.

Answer

Uso spesso “true” e “false” poiché sono anche comandi che restituiscono semplicemente successo e fallimento rispettivamente. Quindi puoi fare

if "$phone_missing"; then ... 

Rispondi

Ecco un modo per farlo questo, pur mantenendo i valori vero / falso.

 phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is true." fi  

Le virgolette doppie intorno $phone_missing serve a proteggere dal caso in cui la variabile phone_missing non sia definita affatto. Un altro idioma comune per evitare questo è [ x$phone_missing != xfalse ], ma le virgolette mi sembrano più naturali.

Il suggerimento si trova nella bash pagina della guida per test:

 STRING True if string is not empty. ... ! EXPR True if expr is false. 

Quindi, in pratica [ $foo ] sarà vero se $foo non è vuoto. Non è vero o falso, solo non vuoto. [ ! $foo ] è vero se $ foo è vuoto o non definito.

Puoi sempre cambiare il tuo codice impostando phone_missing su un non -valore vuoto e, che denoterà vero. Se phone_missing non è impostato (o vuoto – phone_missing=""), sarà falso. Altrimenti, dovresti utilizzare gli operatori di verifica delle stringhe (= e !=).

Laltro piccolo problema è Lincarico. Lo hai come $phone_missing=true, mentre dovrebbe essere phone_missing=true (nessun segno di dollaro).

Scusa se questo è un po denso, è perché io lo sono. È stata una lunga giornata. 🙂

Risposta

Altre risposte ti hanno dato una soluzione, ma ti spiegherò cosa cera di sbagliato nel pensiero originale.

Le variabili Bash non hanno tipi, quindi non esiste una variabile booleana o un valore come vero o falso. Fondamentalmente tutte le variabili bash sono solo stringhe.

Quando si verifica una variabile / stringa in bash senza specificare il tipo di test (-n o -z), per impostazione predefinita sarà un -n (stringa di lunghezza diversa da zero).

Quindi [ "$var" ] è equivalente a [ -n "$var" ]. Finché $var contiene almeno 1 carattere, è stato valutato come vero.

Poiché hai negato lespressione, [ ! "$var" ] è equivalente a [ ! -n "$var" ]. Quindi, se $var contiene almeno 1 carattere, lespressione è falsa.

Poiché false (che è solo una stringa) contiene 5 caratteri, lespressione è falsa. Se non importa quale stringa hai impostato phone_missing su (true, 0, 1), lespressione sarà sempre false perché phone_missing ha una lunghezza diversa da zero. Lunico modo per renderlo true è phone_missing="" poiché è di lunghezza zero.

Risposta

Non utilizzare string per booleano. Usa numero intero.

Input:

val=1 ((val)) && echo "true" || echo "false" val=0 ((val)) && echo "true" || echo "false" 

Output:

true false 

Fonte :

((espressione))

Lespressione viene valutata in base alle regole descritte di seguito in VALUTAZIONE ARITMETICA. Se il valore dellespressione è diverso da zero, lo stato di ritorno è 0; altrimenti lo stato di ritorno è 1. Questo è esattamente equivalente a let “espressione”.

Risposta

Lavrei fatto come commento per supportare James Ko, ma non avevo il rappresentante per commentare o votare pubblicamente.

Il problema qui è che le parentesi [] sono notazioni per eseguire un test di confronto come luguaglianza di valori o stringhe.

La veridicità delle stringhe in bash per una stringa vuota è "" (stringa vuota) restituisce false (valore di ritorno 1) e qualsiasi stringa non vuota “false” “true “o” bob “è tuo zio” restituisce true (valore di ritorno 0).

Puoi dimostrarlo a te stesso con:

 if [ "foo" ]; then echo true is $?; else echo false is $?; fi 

La $? sopra è una variabile speciale che contiene lo stato di uscita dellultimo comando (0 esito positivo e qualsiasi> 0 per il codice di errore) e restituirà true is 0. Puoi sostituire "foo" con tutto ciò che desideri e il risultato sarà lo stesso tranne se lo sostituisci con una stringa vuota "" o "", nel qual caso valuterà la condizione else e restituirà false is 1.

Quando si utilizza [ ] racchiude listruzione interna come! $ phone_missing viene valutata e quindi restituisce un 0 per true o 1 per false al contro if dichiarazione. Poiché la parentesi valuta i confronti tra stringhe e valori, $ phone_missing viene prima espanso alla stringa non vuota “false” che viene valutata da [] come stringa non vuota (o true) e quindi! inverte il risultato che fa sì che listruzione if ottenga un falso (o restituisca il valore 1) e salta il corpo condizionale che esegue listruzione else se presente.

Come disse James Ko, la notazione sarebbe semplicemente passare il variabile tenendo il tuo “booleano” per listruzione di controllo if. Nota che in bash un booleano true e false devono essere minuscole come in: bool_true = true bool_false = false Qualsiasi altro caso lo farà valutare come stringhe e non come booleano.

Quindi usando il tuo esempio e la risposta di James Ko sarebbe:

phone_missing=false echo "missing $phone_missing" if ! $phone_missing then echo "Lost phone at $readabletime" $phone_missing=true fi 

o come io preferisco per la leggibilità (sintatticamente lo stesso e James Ko “s)

phone_missing=false echo "missing $phone_missing" if ( ! $phone_missing ); then echo "Lost phone at $readabletime" $phone_missing=true fi 

Altre risposte come quella di Alexios stanno letteralmente controllando il contenuto della stringa. In modo che una delle seguenti condizioni risulterebbe falsa:

phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == Bobs_your_uncle ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi 

Risposta

La sintassi corretta è if ! $bool; then [statements]; fi.

Esempio:

bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi 

Risultato: This is correct!

Commenti

  • Cè un nocciolo di verità nella tua risposta, ma, in mancanza di spiegazioni, causa di più confusione di quanto rimedi. Inoltre, è poco più che una ripetizione di una delle risposte precedenti. Se non desideri che la tua risposta venga rimossa, spiega perché è corretta.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *