Hacer referencia a variables en un script de shell

Hacer referencia a variables en un script de shell

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 $vary ${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, $fooy ${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 $fooo ${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 $fooo ${foo}, el shelldividirel valor guardado en la variable en espacios en blanco (esto se puede cambiar estableciendo la IFSvariable 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 fooy *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 rmen lugar de echoaunque.

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:

información relacionada