variable una script resultado pasar parametros guardar funciones entorno dobles dentro cómo crear concatenar con comillas comando bash shell dotfiles

bash - una - ¿Debo usar comillas en los nombres de ruta de entorno?



variables en bash (3)

Estoy en el proceso de limpiar todos mis archivos de configuración en un intento de hacerlos lo más legibles posible. He estado buscando una guía de estilo sobre el uso de comillas al exportar rutas en, por ejemplo, un archivo ~/.bashrc :

export PATH="/users/me/path:$PATH"

vs

export PATH=/users/me/path:$PATH

La guía de estilo de shell de Google sugiere evitar citas para nombres de ruta. En contraste, muchos de los repositorios de archivos de puntos populares (como Zach Holman here ) usan comillas. ¿Hay situaciones en las que es una ventaja usar comillas en la ruta?


Utilicé estas respuestas arriba cuando establecí nombres de rutas de entorno en un archivo .env de ventana acoplable, y obtuve bits. Pongo esto aquí para cualquier otra persona que busque cómo definir las variables de entorno para la ventana acoplable.

Docker compose lee las variables de entorno de un archivo .env que existe en la misma carpeta que la ventana acoplable se ejecuta como se indica aquí https://docs.docker.com/compose/env-file.

Sin embargo, en lugar de envolver el valor entre comillas, el componente de Docker necesita la variable de entorno definida sin comillas, a menos que las comillas formen parte del valor. Una vez más, como se indica en la url anterior

No hay un manejo especial de comillas (es decir, serán parte del VAL, se le ha advertido)

Estaba intentando configurar NODE_PATH=./src para que las rutas absolutas funcionen en una aplicación de reacción que está desplegando la NODE_PATH="./src" acoplable, pero la había escrito como NODE_PATH="./src" . Esta advertencia me sacó de 4 horas de conejo.


test 123 es un nombre de ruta válido en UNIX. Tratar

PATH=test 123

Volverá

123: command not found

O incluso

export PATH=test 123

que volverá

bash export: `123'': not a valid identifier

¿Responde tu pregunta?

Sinceramente, no seguiría esas guías de estilo de cuarta fiesta. Aunque me sorprende que incluso Google anuncie consejos tan equivocados.

Yo seguiría:

(para ser cuidadosamente extendido)


Punta del sombrero a gniourf_gniourf y @chepner por su ayuda.

tl; dr

Para estar seguro, doble cita: funcionará en todos los casos, en todas las carcasas tipo POSIX.

Si desea agregar una ruta basada en ~ , deje selectivamente ~/ unquoted para asegurarse de que ~ se expande; Ej .: export PATH=~/"bin:$PATH" . Vea a continuación las reglas de expansión en asignaciones de variables.
Alternativamente, simplemente use $HOME dentro de una cadena de comillas dobles:
export PATH="$HOME/bin:$PATH"

NOTA: Lo siguiente se aplica a bash , ksh y zsh , pero NO a (en su mayoría) shells estrictamente compatibles con POSIX como dash ; por lo tanto, cuando apunta a /bin/sh , DEBE citar el RHS de export . [1]

  • Las comillas dobles son opcionales , SOLAMENTE SI la parte literal de su RHS (el valor a asignar) no contiene espacios en blanco ni otros metacaracteres de shell.
  • Si los valores de las variables a las que se hace referencia contienen espacios en blanco / metacaracteres o no, no importa, consulte a continuación.
    • De nuevo: importa con sh , cuando se usa la export , así que siempre doble comillas allí.

La razón por la que puede salir sin comillas dobles en este caso es que las declaraciones de asignación de variables en shells POSIX interpretan su RHS de manera diferente a los argumentos pasados ​​a los comandos , como se describe en la sección 2.9.1 de la especificación POSIX:

  • Específicamente, aunque la división de palabras inicial se realiza, solo se aplica a la RHS sin expandir (en bruto) (por eso es necesario citar con espacios en blanco / metacaracteres en literales ), y no a sus resultados .

  • Esto solo se aplica a las declaraciones de cesión genuinas del formulario.
    <name>=<value> en todos los shells similares a POSIX , es decir, si no hay un nombre de comando antes del nombre de la variable; tenga en cuenta que eso incluye asignaciones ante un comando para definir variables de entorno ad hoc, por ejemplo, foo=$bar cmd ...

  • Las asignaciones en el contexto de otros comandos siempre deben estar entre comillas dobles , para estar seguros:

    • Con sh (en un shell (en su mayoría) estrictamente compatible con POSIX como un dash ) una asignación con export se trata como un comando regular , y la parte foo=$bar se trata como el primer argumento de la export incorporada y, por lo tanto, se trata como siempre (sujeto a la división de palabras del resultado , también).
      (POSIX no especifica ningún otro comando que involucre asignación de variables (explícita); declare , typeset y local son extensiones no estándar).

    • bash , ksh , zsh , en una desviación comprensible de POSIX, extiende la lógica de asignación para export foo=$bar y typeset/declare/local foo=$bar también. En otras palabras: en bash , ksh , zsh , export/typeset/declare/local comandos export/typeset/declare/local se tratan como asignaciones , por lo que no es estrictamente necesario citar .

      • Quizás sorprendentemente, el dash , que también optó por implementar la función incorporada local no es -POSIX [2] , NO le extiende la lógica de asignación; Sin embargo, es consistente con su comportamiento de export .
    • Las asignaciones pasadas a env (por ejemplo, env foo=$bar cmd ... ) también están sujetas a expansión como un argumento de comando y, por lo tanto, necesitan comillas dobles, excepto en zsh .

      • El hecho de que env actúe de forma diferente a la export en ksh y bash en este sentido se debe al hecho de que env es una utilidad externa , mientras que la export es un shell incorporado .
        (El comportamiento de zsh difiere fundamentalmente del de los otros shells cuando se trata de referencias de variables sin comillas).
  • La expansión de Tilde ( ~ ) ocurre de la siguiente manera en declaraciones de asignación genuinas :

    • Además de que ~ necesita comillas , como es habitual, también se aplica solo:
      • Si todo el RHS es ~ ; p.ej:
        • foo=~ # same as: foo="$HOME"
      • De lo contrario: solo si se cumplen las dos condiciones siguientes:
        • Si ~ inicia la cadena o está precedido por un sin comillas :
        • si ~ es seguido por un / comillas .
        • p.ej,
          foo=~/bin # same as foo="$HOME/bin"
          foo=$foo:~/bin # same as foo="$foo:$HOME/bin"

Ejemplo

Este ejemplo demuestra que, en bash , ksh y zsh , puede salir sin comillas dobles, incluso cuando utiliza la export , pero no lo recomiendo .

#!/usr/bin/env bash # or ksh or zsh - but NOT /bin/sh! # Create env. variable with whitespace and other shell metacharacters export FOO="b:c &|<> d" # Extend the value - the double quotes here are optional, but ONLY # because the literal part, ''a:`, contains no whitespace or other shell metacharacters. # To be safe, DO double-quote the RHS. export FOO=a:$foo # OK - $FOO now contains ''a:b:c &|<> d''

[1] Como @gniourf_gniourf señala: el uso de export para modificar el valor de PATH es opcional, porque una vez que una variable se marca como exportada, puede usar una asignación regular ( PATH=... ) para cambiar su valor.
Dicho esto, aún puede optar por utilizar la export , para que sea explícito que la variable que se está modificando se exporta.

[2] @gniourf_gniourf indica que una versión futura del estándar POSIX puede introducir el componente interno local .