web-dev-qa-db-fra.com

Comment imprimer / echo les variables d'environnement?

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
43
ThomasReggi

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
48
heemayl

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:

  • comme un environnement variable
  • c'est-à-dire défini uniquement pour la commande appelée .

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:

  • a Shell variable NAME (uniquement) plutôt qu'un environnement variable
    • si 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).
  • que continue à vivre après la commande.

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 .

8
mklement0

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.

2
Ljm Dullaart

Cela fonctionne aussi avec le point-virgule.

NAME=sam; echo $NAME

2
ThomasReggi