
¿Alguien puede explicar por qué es necesario el punto y coma para que LANG
bash 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, $LANG
se expande en_US
antes de que se ejecute cualquier cosa. Una vez que bash
termina de procesar la entrada, bifurca un proceso, lo agrega LANG=Ja_JP
al 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-8
al configurar LANG
. Hoy en día no hay ninguna buena razón para no utilizar Unicode en el siglo XXI.
Respuesta2
VAR=value; somecommand
es 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 VAR
ya sea una variable de entorno, no se exporta al entorno, permanece interna al shell. Una declaración export VAR
exportaría VAR
al medio ambiente.
VAR=value somecommand
es una sintaxis diferente. La asignación VAR=value
es 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 $VAR
funciona
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 VAR
tenía el valor 'hola', entonces echo $VAR
se 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