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.


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.


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.


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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.