Cita una variabile nell'istruzione "if" dello script di shell


9

per esempio

if [ "$FOO" = "true" ]; then

vs

if [ $FOO = "true" ]; then

Qual è il diverso? Sembra che entrambe le due affermazioni funzionino.



@DennisWilliamson Non del tutto, hai bisogno di virgolette sul lato destro degli operatori di uguaglianza e corrispondenza dei pattern (in).
Gilles 'SO- smetti di essere malvagio' il


@Gilles: A volte no. Per le stringhe letterali che contengono spazi o per le stringhe letterali o variabili che contengono i caratteri glob che si desidera essere preso alla lettera , il lato destro deve essere citato: a='foo bar'; [[ $a == "foo bar" ]]. Tuttavia, una variabile che non contiene caratteri glob non deve essere: [[ $a == $a ]]. L'espansione delle parole non viene eseguita tra parentesi quadre doppie. E per la corrispondenza di espressioni regolari, il modello sul lato destro della strada non deve essere citato o sarà preso come stringa letterale: [[ $a =~ .*oo.*r ]](il modello dovrebbe essere in una variabile non-citato, però, invece ...
. In pausa fino a nuovo avviso

di essere incorporato letteralmente come qui). Per pattern matching glob-stile, i personaggi glob non devono essere citati, sia letterale o in una variabile: [[ $a == foo* ]]. Potete fornire ulteriori esempi di un requisito per il preventivo oltre al mio esempio di stringa letterale?
In pausa fino a ulteriore avviso.

Risposte:


6

Se il valore di $FOOè una singola parola che non contiene un carattere jolly \[*?, i due sono identici.

Se $FOOè non assegnato, o vuoto, o più di una parola (cioè contiene spazi bianchi o $IFS), la versione non quotata è un errore di sintassi. Se sembra essere la giusta sequenza di parole (come 0 -eq 0 -o false), il risultato potrebbe essere arbitrario. Pertanto, è buona norma citare sempre le variabili negli script di shell.

Per inciso, "true"non ha bisogno di essere quotato.


3

Per illustrare quali problemi potrebbe causare, ecco alcuni esempi.

Diciamo che abbiamo due variabili come segue:

FOO="some value"
BAR="some value"

Ora abbiamo due variabili che contengono esattamente la stessa stringa / valore. Se abbiamo fatto alcune istruzioni if ​​per testare il risultato, nel tuo caso:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

A questo punto otterrai bash: [: too many arguments. Il $ FOO non quotato contiene ora tre valori, vale a dire '[ , some , value'. [la parola chiave test non sa cosa eseguire perché si aspetta che il primo o il secondo argomento siano un operatore.

Quando citiamo "$ FOO" diciamo esplicitamente ifdi guardare ai giusti valori dove non ha luogo la divisione delle parole.

Un altro esempio:

my_file="A random file.txt"
  • fare rm $my_filesignifica rimuovere 'A' 'random' 'file.txt' che lo rende tre file.
  • facendo rm "$my_file"rimuoverà "Un file.txt casuale" che crea un file.

Spero di non averti confuso con questi esempi.


0

In questo caso specifico non c'è differenza.

Tuttavia, se $FOOcontiene uno spazio o alcuni caratteri speciali, avrai un problema.

Nel "$FOO"caso, utilizzerà la variabile in totale, per rendere la corrispondenza isolandoti dal problema dello spazio.

Tuttavia, se usi $FOOe c'è un caso speciale, questo influenzerà l'istruzione if.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.