variable una resultado para las hat guardar funciones entorno cómo crear configuran como comando bash environment-variables echo

una - Bash: especificando variables de entorno para echo en la línea de comando?



variables de entorno linux bash (6)

El problema, revisitado

Francamente, el manual es confuso en este punto. El manual de GNU Bash dice:

El entorno para cualquier comando o función simple [tenga en cuenta que esto excluye los edificios incorporados] puede aumentarse temporalmente prefijando asignaciones de parámetros, como se describe en los Parámetros de la Concha. Estas declaraciones de asignación afectan solo al entorno visto por ese comando.

Si realmente analiza la oración, lo que está diciendo es que el entorno para el comando / función se modifica, pero no el entorno para el proceso principal. Entonces, esto funcionará:

$ TESTVAR=bbb env | fgrep TESTVAR TESTVAR=bbb

porque el entorno para el comando env se ha modificado antes de ejecutarse. Sin embargo, esto no funcionará:

$ set -x; TESTVAR=bbb echo aaa $TESTVAR ccc + TESTVAR=bbb + echo aaa ccc aaa ccc

debido a cuando la expansión de parámetros es realizada por el shell.

Pasos del intér

Otra parte del problema es que Bash define estos pasos para su intérprete:

  1. Lee su entrada desde un archivo (ver Scripts de shell), desde una cadena suministrada como argumento a la opción de invocación -c (ver Invocar Bash), o desde el terminal del usuario.
  2. Rompe la entrada en palabras y operadores, obedeciendo las reglas de cita descritas en Citando. Estos tokens están separados por metacaracteres. La expansión de alias se realiza mediante este paso (ver Alias).
  3. Analiza los tokens en comandos simples y compuestos (vea Comandos de Shell).
  4. Realiza varias expansiones de shell (ver Expansiones de Shell), rompiendo los tokens expandidos en listas de nombres de archivos (ver Expansión de nombre de archivo) y comandos y argumentos.
  5. Realiza las redirecciones necesarias (ver Redirecciones) y elimina los operadores de redirección y sus operandos de la lista de argumentos.
  6. Ejecuta el comando (ver Ejecución de comandos).
  7. Opcionalmente, espera que el comando complete y recopile su estado de salida (consulte el estado de la salida).

Lo que sucede aquí es que los builtins no tienen su propio entorno de ejecución, por lo que nunca ven el entorno modificado. Además, los comandos simples (por ejemplo, / bin / echo) obtienen un entorno modificado (por lo que el ejemplo de env funcionó) pero la expansión del shell se lleva a cabo en el entorno actual en el paso # 4.

En otras palabras, no está pasando ''aaa $ TESTVAR ccc'' a / bin / echo; está pasando la cadena interpolada (como se expandió en el entorno actual) a / bin / echo. En este caso, dado que el entorno actual no tiene TESTVAR , simplemente está pasando ''aaa ccc'' al comando.

Resumen

La documentación podría ser mucho más clara. ¡Qué bueno que hay desbordamiento de pila!

Ver también

http://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Environment

Considera este fragmento:

$ SOMEVAR=AAA $ echo zzz $SOMEVAR zzz zzz AAA zzz

Aquí he puesto $SOMEVAR a AAA en la primera línea, y cuando lo hago eco en la segunda línea, obtengo los contenidos de AAA como se esperaba.

Pero luego, si trato de especificar la variable en la misma línea de comando que el echo :

$ SOMEVAR=BBB echo zzz $SOMEVAR zzz zzz AAA zzz

... No obtengo el BBB como esperaba, obtengo el valor anterior ( AAA ).

¿Es así como se supone que son las cosas? Si es así, ¿cómo es que puedes especificar variables como LD_PRELOAD=/... program args ... y hacer que funcione? ¿Qué me estoy perdiendo?


Aquí hay una alternativa:

SOMEVAR=BBB && echo zzz $SOMEVAR zzz


La razón es que esto establece una variable de entorno para una línea. Pero, echo no hace la expansión, bash does. Por lo tanto, su variable se expande antes de que se ejecute el comando, aunque SOME_VAR es BBB en el contexto del comando echo.

Para ver el efecto, puedes hacer algo como:

$ SOME_VAR=BBB bash -c ''echo $SOME_VAR'' BBB

Aquí la variable no se expande hasta que se ejecuta el proceso secundario, por lo que verá el valor actualizado. si vuelve a seleccionar SOME_VARIABLE en el shell principal, sigue siendo AAA , como se esperaba.


Lo que ves es el comportamiento esperado. El problema es que el shell padre evalúa $SOMEVAR en la línea de comando antes de invocar el comando con el entorno modificado. $SOMEVAR obtener la evaluación de $SOMEVAR diferida hasta después de establecer el entorno.

Sus opciones inmediatas incluyen:

  1. SOMEVAR=BBB eval echo zzz ''$SOMEVAR'' zzz .
  2. SOMEVAR=BBB sh -c ''echo zzz $SOMEVAR zzz'' .

Ambos usan comillas simples para evitar que el shell padre evalúe $SOMEVAR ; solo se evalúa después de establecerse en el entorno (temporalmente, mientras dure el único comando).

Otra opción es usar la notación del subcuadro (como también sugirió Marcus Kuhn en su answer ):

(SOMEVAR=BBB; echo zzz $SOMEVAR zzz)

La variable se establece solo en el subconjunto


Para lograr lo que quiere, use

( SOMEVAR=BBB; echo zzz $SOMEVAR zzz )

Razón:

  • Debe separar la asignación por punto y coma o una nueva línea del próximo comando, de lo contrario no se ejecutará antes de que ocurra la expansión del parámetro para el siguiente comando (eco).

  • Debe realizar la tarea dentro de un entorno de subshell para asegurarse de que no persista más allá de la línea actual.

Esta solución es más corta, más ordenada y más eficiente que algunas de las otras sugeridas, en particular, no crea un nuevo proceso.


SOMEVAR=BBB; echo zzz $SOMEVAR zzz

Usar una ; para separar las declaraciones que están en la misma línea.