Comment imprimer la variable d'environnement en cours de définition?
NAME=sam echo "$NAME" # empty
Vous pouvez voir ici en utilisant eval
cela fonctionne. Est-ce le chemin?
NAME=sam eval 'echo $NAME' # => sam
Celles-ci doivent être différentes commandes, par exemple:
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
Le développement de $NAME
vers une chaîne vide est effectué par le shell avant, avant l'exécution de echo
. Ainsi, au moment où la variable NAME
est transmise à l'environnement de la commande echo
, le développement est déjà fait (chaîne nulle).
Pour obtenir le même résultat en une seule commande:
NAME=sam printenv NAME
Pour apporter les réponses existantes avec une clarification importante:
Comme indiqué, le problème avec NAME=sam echo "$NAME"
est que $NAME
est développé par le Shell actuel avant que l'attribution NAME=sam
ne prenne effet.
Solutions préservant la sémantique d'origine (de la tentative de solution (inefficace) NAME=sam echo "$NAME"
):
Utilisez soit eval
[1] (comme dans la question elle-même), ou printenv
(ajouté par Aaron McDaid à réponse de heemayl ), ou bash -c
(de réponse de Ljm Dullaart ), par ordre décroissant d’efficacité:
NAME=sam eval 'echo "$NAME"' # use `eval` only if you fully control the command string
NAME=sam printenv NAME
NAME=sam bash -c 'echo "$NAME"'
printenv
n'est pas un utilitaire POSIX, mais il est disponible sous Linux et macOS/BSD.
Ce style d'invocation (<var>=<name> cmd ...
) consiste à définir NAME
:
En d'autres termes: NAME
n'existe que pour la commande appelée et n'a aucun effet sur le shell actuel (si aucune variable nommée NAME
n'existait auparavant, il n'y en aura pas après; une variable préexistante NAME
restera inchangée).
POSIX définit les règles pour ce type d'appel dans son chapitre Recherche et exécution de commandes .
Les solutions suivantes fonctionnent de manière très différente (de réponse de heemayl ):
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
Bien qu'ils produisent le même résultat , ils définissent plutôt:
NAME
(uniquement) plutôt qu'un environnement variable echo
était une commande qui s'appuyait sur la variable d'environnement NAME
, elle ne serait pas définie (ou potentiellement définie différemment des précédentes).Notez que chaque variable d'environnement est également exposée en tant que variable Shell, mais que l'inverse n'est pas vrai: les variables Shell ne sont visibles que par le Shell actuel et ses sous-shell, mais pas par les processus enfants. , tels que les utilitaires externes et les scripts (sans source) (à moins qu’ils ne soient marqués comme variables d’environnement avec export
ou declare -x
).
[1] Techniquement, bash
enfreint POSIX ici (comme zsh
): Puisque eval
est un spécial Shell construit- in, l'assignation précédente NAME=sam
devrait faire en sorte que la variable $NAME
reste dans la portée une fois la commande terminée, mais ce n'est pas ce qui se produit.
Toutefois, lorsque vous exécutez bash
en mode de compatibilité POSIX, il est conforme à la conformité .dash
et ksh
sont toujours conformes.
Les règles exactes sont compliquées et certains aspects sont laissés à l’application. à nouveau, voir Recherche et exécution de commandes .
En outre, la clause de non-responsabilité habituelle s’applique: tilisez eval
uniquement sur les entrées que vous contrôlez totalement ou que vous faites confiance de manière implicite .
La syntaxe
variable=value command
est souvent utilisé pour définir des variables d'environnement pour un processus spécifique. Cependant, vous devez comprendre quel processus obtient quelle variable et qui l'interprète. A titre d'exemple, en utilisant deux shells:
a=5
# variable expansion by the current Shell:
a=3 bash -c "echo $a"
# variable expansion by the second Shell:
a=3 bash -c 'echo $a'
Le résultat sera 5 pour le premier écho et 3 pour le second.
Cela fonctionne aussi avec le point-virgule.
NAME=sam; echo $NAME