Mientras escribía un código descubrí que esta línea:
$ TZ="America/Los_Angeles" date; echo "$TZ"
Thu Dec 24 14:39:15 PST 2015
Indica correctamente el tiempo real en "Los Ángeles" y que el valor de la variable TZ
no se retiene. Todo como debería esperarse.
Sin embargo, con esta línea, que solía expandir algunos formatos hasta la fecha, y que esencialmente ejecuta lo mismo, conserva el valor de TZ:
TZ="America/Los_Angeles" eval date; echo "$TZ"
Thu Dec 24 14:41:34 PST 2015
America/Los_Angeles
Después de varias pruebas más, descubrí que esto sucede solo en algunos proyectiles. Sucede en guión, ksh pero no en bash o zsh.
Q's
Las preguntas son:
- ¿Por qué se retiene el valor de TZ en el shell actual?
- ¿Cómo podría evitarse / controlarse (si es posible)?
Adicional.
Realicé pruebas en varios depósitos con estas dos líneas:
myTZ="America/Los_Angeles"
unset TZ; { TZ="$myTZ" date; } >/dev/null; echo -n " direct $TZ"
unset TZ; { TZ="$myTZ" eval date; } >/dev/null; echo " evaled $TZ"
Y esto resulta:
/bin/ash : direct evaled America/Los_Angeles
/bin/dash : direct evaled America/Los_Angeles
/bin/sh : direct evaled America/Los_Angeles
/bin/bash : direct evaled
/bin/ksh93 : direct evaled America/Los_Angeles
/bin/lksh : direct evaled America/Los_Angeles
/bin/mksh : direct evaled America/Los_Angeles
/bin/zsh : direct evaled
/bin/zsh4 : direct evaled
El valor TZ afecta al shell en ejecución en todos los shells excepto bash y zsh.
Resulta que hay una razón muy específica para este comportamiento.
La descripción de lo que sucede es un poco más larga.
Solo tareas.
Una línea de comando hecha (solo) de asignaciones establecerá las variables para este shell.
Se retendrá el valor de los vars asignados.
Comando externo
Las asignaciones antes de un comando externo establecen variables solo para ese shell:
Y me refiero a "externo" como cualquier comando que debe buscarse en PATH.
Esto también se aplica a las incorporaciones normales (como cd, por ejemplo):
Hasta aquí todo es como se suele esperar.
Empotrados especiales.
Pero para incorporaciones especiales, POSIX requiere que los valores estén establecidos para este shell .
Estoy usando una llamada para
sh
suponer quesh
es un shell compatible con POSIX.Esto no es algo que generalmente se usa.
Esto significa que las asignaciones colocadas delante de cualquiera de esta lista de incorporaciones especiales retendrán los valores asignados en el shell actual:
Esto sucederá si un shell funciona según la especificación POSIX.
Conclusión:
Es posible establecer variables para un solo comando, cualquier comando, asegurándose de que el comando no esté integrado de manera especial. El comando
command
es una construcción regular. Solo le dice al shell que use un comando, no una función. Esta línea funciona en todos los shells (excepto ksh93):En tal caso, los vars ayb se establecen para el entorno del comando de comando y se descartan después de eso.
En cambio, esto retendrá los valores asignados (excepto bash y zsh):
Tenga en cuenta que la asignación después de eval está entre comillas simples para protegerla de expansiones no deseadas.
Entonces: Para colocar variables en el entorno del comando, use
command eval
:fuente