
En un script de shell, si defino una variable como FOO=25
, ¿hay alguna diferencia entre hacer referencia a ella como $FOO$
y ${FOO}$
?
Respuesta1
En la mayoría de las situaciones, ambos $var
y ${var}
son iguales. (¡Tenga en cuenta que no debe utilizar a $
al final!)
Un ejemplo en el que necesita llaves es cuando necesita colocar una variable en una cadena continua.
Ejemplo:
var=hel
echo ${var}lo
saldrá hello
.
Respuesta2
Para responder a su pregunta principal, ${foo}
se llama"expansión de parámetros". Para ser precisos, él $
mismo inicia la expansión de parámetros, { }
en realidad son opcionales segúnla especificación POSIX, pero puede resultar útil para indicar el final del nombre de la variable:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
Básicamente, $foo
y ${foo}
son idénticos. Aparte de casos como el anterior o cuando estés haciendomanipulación de cuerdas, son completamente equivalentes.
Sin embargo, no deberías utilizar ninguno de ellos. La regla general es que, con muy pocas excepciones, debessiempreusar "$foo"
o "${foo}"
y nunca $foo
o ${foo}
. Siempre debes citar tus variables para evitar invocar el operador split+glob (más sobre esto más adelante). Ciertamente no quieres $foo$
. La final $
es irrelevante:
$ foo="bar"
$ echo "$foo$"
bar$
Entonces, aunque las variables sin comillas a veces están bien:
$ echo $foo
bar
Por lo general, no lo son y realmente deben evitarse:
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Tenga en cuenta que los corchetes tampoco ayudan aquí:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Cuando uses $foo
o ${foo}
, el shelldividirel valor guardado en la variable en espacios en blanco (esto se puede cambiar estableciendo la IFS
variable en otra cosa) en una lista y luego, cada elemento de la lista se trata como unglobopatrón y expandido a cualquier archivo o directorio coincidente. Esto se conoce como eldividir+globooperador. Para ilustrar, considere un directorio con dos archivos:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
Ahora, establezcamos una variable para foo *
:
$ foo="foo *"
¿Qué pasa si intentamos comprobar si existe un archivo con ese nombre?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
La variable se dividió en foo
y *
y, dado que *
es un comodín que coincide con cualquier cadena, el shell le indica que foo *
existe un archivo llamado. Sin embargo, si lo citamos correctamente, esto no sucede:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Éste fue un ejemplo trivial para ilustrar el punto. Imagínese si hubiera usado rm
en lugar de echo
aunque.
Entonces, primera regla:cite siempre sus variables.Puede utilizar cualquiera de los dos "$foo"
o "${foo}"
citarlo de cualquier manera. Para obtener más detalles sobre el uso seguro de variables, consulte estas publicaciones: