Cuándo usar un punto y coma entre las variables de entorno y un comando

Cuándo usar un punto y coma entre las variables de entorno y un comando

¿Alguien puede explicar por qué es necesario el punto y coma para que LANGbash lo considere actualizado?

No funciona:

> LANG=Ja_JP bash -c "echo $LANG"
en_US

Obras:

> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP

Estoy trabajando con bash 4.1.10 en Linux y con la misma versión en cygwin.

Respuesta1

Los parámetros y otros tipos de expansiones se realizan cuando se lee el comando,antesse ejecuta.

La primera versión, LANG=Ja_JP bash -c "echo $LANG"es un comando único. Una vez analizado como tal, $LANGse expande en_USantes de que se ejecute cualquier cosa. Una vez que bashtermina de procesar la entrada, bifurca un proceso, lo agrega LANG=Ja_JPal entorno como se esperaba y luego lo ejecuta bash -c echo en_US.

Puede evitar la expansión con comillas simples, es decir, LANG=Ja_JP bash -c 'echo $LANG'salidas Ja_JP.

Tenga en cuenta que cuando tiene una asignación de variable como parte de un comando, la asignación solo afecta el entorno de ese comando y no el de su shell.

La segunda versión, LANG=Ja_JP; bash -c "echo $LANG"en realidad, consta de dos comandos separados ejecutados en secuencia. La primera es una asignación de variable simple sin un comando, por lo que afecta su shell actual.

Por lo tanto, sus dos fragmentos son fundamentalmente diferentes a pesar de la distinción superficial de un solo archivo ;.

Completamente fuera de tema, pero podría recomendar agregar un archivo .UTF-8al configurar LANG. Hoy en día no hay ninguna buena razón para no utilizar Unicode en el siglo XXI.

Respuesta2

VAR=value; somecommandes equivalente a

VAR=value
somecommand

Estos son comandos no relacionados que se ejecutan uno tras otro. El primer comando asigna un valor a la variable del shell VAR. A menos que VARya sea una variable de entorno, no se exporta al entorno, permanece interna al shell. Una declaración export VARexportaría VARal medio ambiente.

VAR=value somecommandes una sintaxis diferente. La asignación VAR=valuees al entorno, pero esta asignación sólo se realiza en el entorno de ejecución de somecommand, no para la posterior ejecución del shell.

A modo de ejemplo:

# Assume neither VAR1 nor VAR2 is in the environment
VAR1=value
echo $VAR1                        # displays "value"
env | grep '^VAR1='               # displays nothing
VAR2=value env | grep '^VAR2='    # displays "VAR2=value"
echo $VAR2                        # displays nothing

Respuesta3

Este es el resumen de lo que recopilé de la investigación:

Hay dos tipos: variables env y variables de shell.

Una variable de entorno está disponible en un programa y sus programas/procesos/subcapas secundarios. Una variable de shell solo está disponible en el shell actual.

https://askubuntu.com/a/26322/326584

primero como echo $VARfunciona

Siempre que terminal/shell/bash ve el símbolo $, hace algo llamado "expansión de parámetros". Lo que significa que las variables se reemplazan con valores.

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

Entonces, si VARtenía el valor 'hola', entonces echo $VARse convierte en echo 'hello'.

lo que significa que esto funciona...

TEST=123 
echo $TEST
// 123

pero lo siguiente no funciona porque la variable fue reemplazada ANTES de que el comando pudiera configurar la variable.

TEST2=999 echo $TEST2
// nothing...

pero si agregas el punto y coma..

TEST2=999; echo $TEST2

es lo mismo que..

TEST2=999
echo $TEST2

.. que funciona igual que antes.

Y dado que las variables de shell no se pasan a subprocesos/secundarios, cuando llamas a un comando, se crea un nuevo proceso, entonces...

TEST3=111 
node -e 'console.log(process.env.TEST3)' 

o

TEST3=111 
printenv TEST3

ambos no imprimen nada. Las variables de Shell no son heredadas por los procesos chld. Utilice exportar para hacer una variable de shell, una variable de entorno.

export TEST3=111 
printenv TEST3
//111

Hay una excepción...

VAR=123 printenv VAR
VAR=123 VAR2=456 printenv VAR2 //even multiple vars

Básicamente, si se escribe así y justo después de llamar al comando, solo establece temporalmente la var de entorno para ese comando. Ni siquiera establece Shell var. Piense en ello como una sintaxis completamente nueva.

VAR=123 printenv VAR // 123
echo $VAR // nothing
VAR=123
echo $VAR // 123

información relacionada