En mi entorno Bash, uso variables que contienen espacios y uso estas variables dentro de la sustitución de comandos.
¿Cuál es la forma correcta de citar mis variables? ¿Y cómo debo hacerlo si estos están anidados?
DIRNAME=$(dirname "$FILE")
o cito fuera de la sustitución?
DIRNAME="$(dirname $FILE)"
o ambos?
DIRNAME="$(dirname "$FILE")"
¿O uso tildes de retroceso?
DIRNAME=`dirname "$FILE"`
¿Cuál es la manera correcta de hacer esto? ¿Y cómo puedo verificar fácilmente si las comillas están configuradas correctamente?
Respuesta aceptada:
En orden de peor a mejor:
DIRNAME="$(dirname $FILE)"
no hará lo que quieras si$FILE
contiene espacios en blanco (o cualquier carácter$IFS
contiene actualmente) o caracteres globales[?*
.DIRNAME=`dirname "$FILE"`
es técnicamente correcto, pero no se recomiendan los acentos graves para la expansión de comandos debido a la complejidad adicional al anidarlos y el procesamiento de barra invertida adicional que ocurre dentro de ellos.DIRNAME=$(dirname "$FILE")
es correcto, pero solo porque se trata de una asignación a una variable escalar (no de matriz). Si usa la sustitución de comando en cualquier otro contexto, comoexport DIRNAME=$(dirname "$FILE")
odu $(dirname -- "$FILE")
, la falta de comillas causará problemas si el resultado de la expansión contiene espacios en blanco o caracteres pegajosos.DIRNAME="$(dirname "$FILE")"
(excepto por el--
que falta , ver más abajo) es la forma recomendada. Puede reemplazarDIRNAME=
con un comando y un espacio sin cambiar nada más, ydirname
recibe la cadena correcta.
Para mejorar aún más:
DIRNAME="$(dirname -- "$FILE")"
funciona si$FILE
comienza con un guión.DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit
funciona incluso si$FILE
El nombre de directorio de 's termina con una nueva línea, ya que$()
corta las líneas nuevas al final de la salida, ambas agregadas pordirname
y los que pueden ser parte de los datos reales.
Puede anidar expansiones de comandos tanto como desee. Con $()
siempre crea un nuevo contexto de cotización, por lo que puede hacer cosas como esta:
foo "$(bar "$(baz "$(ban "bla")")")"
Tu no quiero probar eso con acentos graves.