web-dev-qa-db-fra.com

Définition de la variable d'environnement pour un appel de programme dans bash en utilisant env

J'essaie d'appeler une commande Shell avec un environnement modifié via la commande env.

Selon le manuel

env HELLO='Hello World' echo $HELLO

devrait echo Hello World, mais ça ne le fait pas . Si je le fais

HELLO='Hello World' bash -c 'echo $HELLO'

il imprime Hello World comme prévu (grâce à cette réponse pour cette information).

Qu'est-ce que j'oublie ici?

Salutations, Niklas

25
Niklas

C'est parce que dans votre premier cas, votre Shell actuel développe la variable $ HELLO avant d'exécuter les commandes. Et il n'y a pas de variable HELLO définie dans votre Shell actuel.

env HELLO='Hello World' echo $HELLO

fera ceci:

  • développer les variables données, dans ce cas $ HELLO
  • lancez env avec les 3 arguments 'HELLO = Hello World', 'echo' et '' (une chaîne vide, car aucune variable HELLO n'est définie dans le shell actuel).
  • La commande env s'exécutera et définira HELLO = 'Hello World' dans son environnement.
  • env exécutera echo avec l'argument '' (une chaîne vide)

Comme vous le voyez, le shell actuel a développé la variable $ HELLO, qui n'est pas définie.

HELLO='Hello World' bash -c 'echo $HELLO'

fera ceci:

  • définir la variable HELLO='Hello World pour la commande suivante
  • lancez bash avec les 2 arguments '-c' et 'echo $ HELLO'
  • puisque le dernier argument est placé entre guillemets simples, rien à l'intérieur n'est développé
  • la nouvelle bash exécutera à son tour la commande echo $HELLO
  • Pour exécuter echo $ HELLO dans le nouveau sous-shell bash, bash commence par développer tout ce que vous pouvez, $ HELLO dans ce cas, et le Shell parent l'a défini pour nous comme étant "Hello World".
  • Le sous-shell s'exécute echo 'Hello World'

Si vous avez essayé de le faire, par exemple ce:

env HELLO='Hello World' echo '$HELLO'

  • Le shell actuel développerait tout ce qu’il pourrait, ce qui n’est rien puisque $ HELLO est entre guillemets simples
  • lancer env avec les 3 arguments 'HELLO = Hello World', 'echo' et '$ HELLO'
  • La commande env s'exécutera et définira HELLO = 'Hello World' dans son environnement.
  • env exécutera echo avec l'argument '$ HELLO'

Dans ce cas, aucun Shell ne développera le $ HELLO, donc echo reçoit la chaîne $HELLO et l'imprime. L'expansion variable est faite par les coquilles seulement.

43
nos

Je pense que ce qui se passe est similaire à cette situation dans laquelle j'étais aussi perplexe.

En un mot, le développement de la variable dans le premier cas est effectué par le Shell actuel qui n'a pas $HELLO dans son environnement. Dans le second cas, toutefois, les guillemets simples empêchent le Shell actuel de procéder à l'expansion des variables, de sorte que tout fonctionne comme prévu.

Notez que la modification de guillemets simples en guillemets doubles empêche cette commande de fonctionner comme vous le souhaitez:

HELLO='Hello World' bash -c "echo $HELLO"

Maintenant, cela échouera pour la même raison que la première commande de votre question.

4
Lev Levitsky

Cela fonctionne et est bon pour moi

$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR"
Hello World!!!
1
deFreitas

Voici un moyen plus simple de confirmer que Shell fonctionne comme prévu.

env A=42 env
env

La première commande exécute A sur 42 et env. La deuxième commande exécute également env. Comparez la sortie des deux.

0
William Entriken