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$FILEcontiene espacios en blanco (o cualquier carácter$IFScontiene 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, ydirnamerecibe la cadena correcta.
Para mejorar aún más:
DIRNAME="$(dirname -- "$FILE")"funciona si$FILEcomienza con un guión.DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exitfunciona incluso si$FILEEl 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 pordirnamey 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.