Comment faire en sorte que les variables d'environnement "exportées" dans un script shell restent fidèles?

54

J'ai plusieurs comptes Amazon EC2 et je veux pouvoir rapidement changer de variables, telles que $EC2_HOME, à l'aide d'un script.

J'ai un script shell configuré comme ceci:

#!/bin/sh
export EC2_HOME=/home/me/.ec2
echo $EC2_HOME

Lorsque je lance le script, je sais que EC2_HOMEc'est défini, mais je pensais que l'utilisation exportferait en sorte que la variable reste fidèle une fois le script terminé. Ça ne marche pas, car courir echo $EC_HOMEne montre rien.

Je sais que ce doit être une connaissance très rudimentaire des scripts Linux, mais je ne le sais pas. J'ai essayé de chercher des questions connexes sans succès - alors je m'excuse s'il s'agit d'un doublon.

cwd
la source

Réponses:

60

Vous devriez source votre script, avec

. ./script

ou

source ./script
enzotib
la source
19
La raison en est que votre script génère un nouveau processus shell en tant qu'enfant du shell actuel. Les modifications de l'environnement que vous apportez dans le processus enfant ne peuvent pas affecter le parent. Lorsque vous utilisez .ou source, vous ne créez pas de nouveau processus enfant, vous exécutez les commandes dans le shell actuel.
Glenn Jackman
1
@glennjackman J'ai un problème similaire et j'ai essayé votre solution, mais elle me déconnecte du shell lorsque je le fais .ou source. Pourquoi cela arrive-t-il ?
Patryk
7
@Patryk: peut-être que votre script a une exitdéclaration, il n'est donc pas approprié de l'obtenir.
enzotib
Bien que source ./scriptfonctionne parfaitement bien, sudo source ./script.shdit sudo: source: command not found. Comment puis-je faire cela en utilisant sudo?
71GA
1
@ 71GA: en fonction des préférences de compilation pour sudoet en fonction des paramètres de configuration, /etc/sudoersvous pouvez ou non conserver votre environnement lorsque vous exécutez des commandes avec sudo. Je vous suggère d'essayer de source votre script, puis d'exécuter l' option sudoavec -Epour préserver l'environnement. Si cela ne fonctionne pas, je suppose que vous pouvez très peu faire.
enzotib
36

Lorsque vous exécutez un script, il obtient son propre shell et son propre environnement, qui disparaissent dès que le script est terminé. Pour conserver les variables d'environnement, sourcez le script dans votre shell actuel:

$ source ./a.sh

ou de manière équivalente (mais un peu plus portable), utilisez la commande POSIX :

$ . ./a.sh

Ensuite, les définitions seront placées dans l'environnement de votre shell actuel et seront héritées par tous les programmes que vous lancerez à partir de celui-ci.

Pour être plus proche de l'exécution d'un script, . a.shtrouvez a.sh en cherchant dans les répertoires de la PATHvariable d'environnement.


Il y a quelques subtilités dans leur comportement, et si .et sourcesont identiques (ou présents). . ./a.shse comportera certainement de la même manière dans chaque shell compatible POSIX, mais sourceet ., et, . a.shet . ./a.sh, peuvent varier. Pour Bash sourceet .sont les mêmes dans tous les cas; for zsh sourcevérifie toujours d'abord le répertoire courant ; ksh est essentiellement similaire.

Si le nom du script est donné sous forme de chemin (contenant un /), ce chemin est utilisé directement dans tous les cas. La chose la plus fiable à faire est . ./scriptou . /path/to/script.

Michael Homer
la source
1

Juste pour l'enregistrement.

Si vous voulez exécuter un script à partir d’Internet qui exporte env au système

vous pouvez utiliser le format suivant

source <(curl -s -L https://raw.githubusercontent.com/iamwwc/wwcdocker/master/install.sh)

Par exemple:

source <(curl -s -L https://example.com/install.sh)
caramel au beurre
la source
Cela semble dangereux mais utile si vous faites confiance à ce script!
Mark Stewart