En écrivant du code, j'ai découvert que cette ligne:
$ TZ="America/Los_Angeles" date; echo "$TZ"
Thu Dec 24 14:39:15 PST 2015
Donne correctement l'heure réelle à "Los Angeles" et que la valeur de la variable TZ
n'est pas conservée. Tout comme il faut s'y attendre.
Cependant, avec cette ligne, que j'ai utilisée pour développer certains formats à ce jour, et qui exécute essentiellement la même chose, conserve la valeur de TZ:
TZ="America/Los_Angeles" eval date; echo "$TZ"
Thu Dec 24 14:41:34 PST 2015
America/Los_Angeles
Après plusieurs tests supplémentaires, j'ai découvert que cela ne se produit que dans certains obus. Cela se produit en dash, ksh mais pas en bash ou zsh.
Q's
Les questions sont les suivantes:
- Pourquoi la valeur de TZ est-elle conservée dans la coque actuelle?
- Comment cela pourrait-il être évité / contrôlé (si possible)?
Additionnel.
J'ai effectué des tests dans plusieurs shells avec ces deux lignes:
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"
Et cela se traduit:
/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
La valeur TZ affecte le shell en cours d'exécution dans tous les shells sauf bash et zsh.
Il s'avère qu'il y a une raison très spécifique à ce comportement.
La description de ce qui se passe est un peu plus longue.
Uniquement les affectations.
Une ligne de commande composée (uniquement) d'affectations définira les variables de ce shell.
La valeur des vars attribués sera conservée.
Commande externe.
Affectations avant un ensemble de commandes externes de variables pour ce shell uniquement:
Et je veux dire "externe" comme toute commande qui doit être recherchée dans PATH.
Cela s'applique également aux fonctions intégrées normales (comme les cd, par exemple):
Jusqu'à présent, tout est comme prévu.
Intégrés spéciaux.
Mais pour les fonctions intégrées spéciales, POSIX nécessite que les valeurs soient définies pour ce shell .
J'utilise un appel pour
sh
supposer qu'ilsh
s'agit d'un shell compatible POSIX.Ce n'est pas quelque chose qui est habituellement utilisé.
Cela signifie que les affectations placées devant n'importe laquelle de cette liste de modules intégrés spéciaux doivent conserver les valeurs attribuées dans le shell en cours d'exécution:
Cela se produira si un shell fonctionne selon les spécifications POSIX.
Conclusion:
Il est possible de définir des variables pour une seule commande, n'importe quelle commande, en s'assurant que la commande n'est pas une fonction intégrée spéciale. La commande
command
est une fonction intégrée standard. Il indique uniquement au shell d'utiliser une commande, pas une fonction. Cette ligne fonctionne dans tous les shells (sauf ksh93):Dans ce cas, les variables a et b sont définies pour l'environnement de la commande command et supprimées après cela.
Au lieu de cela, cela conservera les valeurs attribuées (sauf bash et zsh):
Notez que l'affectation après eval est entre guillemets simples pour la protéger contre les expansions indésirables.
Donc: Pour placer des variables dans l'environnement de commande, utilisez
command eval
:la source