Sembra che qui ci siano dei malintesi sull'integrato di Bash truee, più specificamente, su come Bash espande e interpreta le espressioni tra parentesi.
Il codice in risposta di Miku non ha assolutamente nulla a che fare con il builtin Bash true, né /bin/true, né alcun altro sapore del truecomando. In questo caso, truenon è altro che una semplice stringa di caratteri e non trueviene mai effettuata alcuna chiamata al comando / builtin, né dall'assegnazione delle variabili, né dalla valutazione dell'espressione condizionale.
Il seguente codice è funzionalmente identico al codice nella risposta del miku:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
L' unica differenza qui è che i quattro caratteri che vengono confrontati sono 'y', 'e', 'a' e 'h' invece di 't', 'r', 'u' ed 'e'. Questo è tutto. Non è stato fatto alcun tentativo di chiamare un comando o un builtin chiamato yeah, né (nell'esempio di miku) non c'è alcun tipo di gestione speciale in corso quando Bash analizza il token true. È solo una stringa, e completamente arbitraria.
Aggiornamento (19-02-2014): dopo aver seguito il link nella risposta di Miku , ora vedo da dove proviene parte della confusione. La risposta di Miku usa parentesi singole, ma lo snippet di codice a cui si collega non usa parentesi. È appena:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Entrambi i frammenti di codice si comporteranno allo stesso modo, ma le parentesi cambiano completamente ciò che accade sotto il cofano.
Ecco cosa sta facendo Bash in ogni caso:
Nessuna parentesi:
- Espandi la variabile
$the_world_is_flatalla stringa "true".
- Tentativo di analizzare la stringa
"true"come comando.
- Trova ed esegui il
truecomando (incorporato o /bin/true, a seconda della versione di Bash).
- Confronta il codice di uscita del
truecomando (che è sempre 0) con 0. Ricorda che nella maggior parte delle shell, un codice di uscita 0 indica il successo e qualsiasi altra cosa indica il fallimento.
- Dal momento che il codice di uscita è 0 (successo), eseguire l'
ifdella dichiarazione thenclausola
Parentesi:
- Espandi la variabile
$the_world_is_flatalla stringa "true".
- Analizza l'espressione condizionale ora completamente espansa, che è della forma
string1 = string2. L' =operatore è l' operatore di confronto delle stringhe di bash . Così...
- Fai un confronto tra stringhe su
"true"e "true".
- Sì, le due stringhe erano uguali, quindi il valore del condizionale è vero.
- Eseguire l'
ifdella dichiarazione thenclausola.
Il codice senza parentesi funziona, poiché il truecomando restituisce un codice di uscita pari a 0, che indica l'esito positivo. Il codice tra parentesi funziona perché il valore di $the_world_is_flatè identico alla stringa letterale truesul lato destro di =.
Solo per riportare il punto a casa, considera i seguenti due frammenti di codice:
Questo codice (se eseguito con i privilegi di root) riavvierà il tuo computer:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Questo codice stampa semplicemente "Bel tentativo". Il comando reboot non viene chiamato.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Aggiornamento (14-04-2014) Per rispondere alla domanda nei commenti sulla differenza tra =e ==: AFAIK, non c'è differenza. L' ==operatore è un sinonimo specifico di Bash =e, per quanto ho visto, funzionano esattamente allo stesso modo in tutti i contesti.
Si noti, tuttavia, che sto parlando in particolare degli operatori di confronto di stringhe =e ==utilizzati in uno dei test [ ]o [[ ]]. Non lo sto suggerendo =e ==sono intercambiabili ovunque in bash.
Ad esempio, ovviamente non è possibile eseguire un'assegnazione variabile con ==, come var=="foo"(bene tecnicamente puoi farlo, ma il valore di varsarà "=foo", perché Bash non sta vedendo un ==operatore qui, sta vedendo un =operatore (assegnazione), seguito da il valore letterale ="foo", che diventa "=foo").
Inoltre, anche se =e ==sono intercambiabili, si dovrebbe tenere a mente che come tali test lavoro non dipende dal fatto che lo si usa all'interno [ ]o [[ ]], e anche sulla necessità o meno gli operandi sono quotati. Puoi leggere ulteriori informazioni al riguardo nella Guida agli script avanzati di Bash: 7.3 Altri operatori di confronto (scorri verso il basso fino alla discussione di =e ==).
trueefalsenel contesto della maggior parte dei frammenti di seguito sono solo stringhe semplici, non ilbash built-ins!!! Si prega di leggere la risposta di Mike Holt di seguito. (Questo è un esempio in cui una risposta altamente votata e accettata è fonte di confusione per l'IMHO e mette in ombra i contenuti perspicaci nelle risposte meno votate)