Cite una variable en la instrucción "if" del script de shell

9

p.ej

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

vs

if [ $FOO = "true" ]; then

Cual es la diferencia? Parece que las dos declaraciones también funcionan.

Ryan
fuente
En Bash, use corchetes dobles y no necesita las comillas y obtiene beneficios adicionales .
Pausado hasta nuevo aviso.
@DennisWilliamson No del todo, necesita comillas en el lado derecho de los operadores de (in) igualdad y coincidencia de patrones.
Gilles 'SO- deja de ser malvado'
@Gilles: A veces no. Para las cadenas literales que contienen espacios o para cadenas literales o variables que contienen caracteres glob que desea ser tomado literalmente , el lado derecho debe ser citado: a='foo bar'; [[ $a == "foo bar" ]]. Sin embargo, una variable que no contiene caracteres glob no tiene que ser: [[ $a == $a ]]. La expansión de palabras no se realiza entre corchetes dobles. Y para la coincidencia de expresiones regulares, el patrón en el lado derecho no se debe citar o se tomará como una cadena literal: [[ $a =~ .*oo.*r ]](sin embargo, el patrón debe estar en una variable sin comillas ...
Pausado hasta nuevo aviso.
de ser incorporado literalmente como aquí). Por estilo pegote coincidencia de patrones, los personajes glob no podrá ser citado, ya sea literal o en una variable: [[ $a == foo* ]]. ¿Puede proporcionar ejemplos adicionales de un requisito para citar además de mi ejemplo de cadena literal?
Pausado hasta nuevo aviso.

Respuestas:

6

Si el valor de $FOOes una sola palabra que no contiene un carácter comodín \[*?, entonces las dos son idénticas.

Si $FOOno está asignado, está vacío o tiene más de una palabra (es decir, contiene espacios en blanco o $IFS), entonces la versión sin comillas es un error de sintaxis. Si resulta ser la secuencia correcta de palabras (como 0 -eq 0 -o false), el resultado podría ser arbitrario. Por lo tanto, es una buena práctica citar siempre variables en scripts de shell.

Por cierto, "true"no necesita ser citado.

200_success
fuente
3

Para ilustrar qué problemas puede causar, aquí hay algunos ejemplos.

Digamos que tenemos dos variables de la siguiente manera:

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

Ahora tenemos dos variables que contienen exactamente la misma cadena / valor. Si hicimos algunas declaraciones if para probar el resultado, en su caso:

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

En este punto lo conseguirás bash: [: too many arguments. El $ FOO sin comillas tiene ahora tres valores, a saber '[ , some , value'. [La palabra clave test no sabe qué ejecutar porque espera que el primer o segundo argumento sea un operador.

Cuando citamos "$ FOO", le pedimos explícitamente ifque mire los valores correctos donde no tiene lugar la división de palabras.

Otro ejemplo:

my_file="A random file.txt"
  • hacer rm $my_filesignifica eliminar 'A' 'random' 'file.txt' que lo convierte en tres archivos.
  • haciendo rm "$my_file"eliminará "Un archivo aleatorio.txt" que crea un archivo.

Espero no haberte confundido con estos ejemplos.

Valentin Bajrami
fuente
0

En este caso específico no hay diferencia.

Sin embargo, si $FOOcontiene un espacio o algunos caracteres especiales, tendrá un problema.

En el "$FOO"caso, usará la variable en total para hacer que la coincidencia lo aísle del problema del espacio.

Sin embargo, si usa $FOOy hay un caso especial, afectará la declaración if.

mdpc
fuente