Comment définir une variable d'environnement uniquement pour la durée du script?

127

Sous Linux (Ubuntu 11.04) en bash, est-il possible de définir temporairement une variable d'environnement qui ne sera différente de la variable normale que pendant la durée du script? Par exemple, dans un script shell, créer une application qui enregistre dans HOME portable en définissant temporairement HOME dans un dossier dans le répertoire de travail actuel, puis en lançant l'application.

suchipi
la source
5
Ce serait plus difficile si vous vouliez que le paramètre dure au - delà de la durée du script
Nemo

Réponses:

120
VAR1=value1 VAR2=value2 myScript args ...
Rockallite
la source
2
Je l'ai fait moi-même plusieurs fois pour courir vblank_mode=0 glxgears. Cela fonctionne, mais cela dit aussi vblank_mode=0: command not foundaprès l'exécution, alors que le préfixe envne cause pas cela. [testing ...] Apparemment, zsh ne l'aime pas (mais l'utilise toujours correctement), mais bash est bien avec. Je suppose que je vais utiliser la envméthode à partir de maintenant.
Chinoto Vokro
2
avec des scripts cela fonctionne mais que diriez-vous de VAR1="hello" echo $VAR1ne rien renvoyer?
Zibri
2
@Zibri il s'agit du moment où l'expansion se produit. Vous pouvez probablement faire quelque chose comme ça:VAR1="hello" bash -c 'echo $VAR1'
cybergrind
Approuvé pour avoir montré que cela est possible même pour plusieurs variables d'environnement.
Binarus le
70
env VAR=value myScript args ...
Glenn Jackman
la source
18
OuVAR=value myScript args ...
Rockallite
9
1. Pourquoi PATH=$PATH:XYZ echo $PATH | grep XYZn'a-t-il pas de sortie? 2. Quelle est la différence entre utiliser et ne pas utiliser env?
qubodup
18
car le shell développe la variable PATH avant d' exécuter la commande echo. Vous devez retarder cette expansion. One way: PATH=$PATH:XYZ sh -c 'echo $PATH' | grep XYZ- les guillemets simples sont la clé ici
glenn jackman
14
Quelle est la différence entre l'utiliser envet ne pas l'utiliser?
Mohammed Noureldin
Cela ne semble pas fonctionner dans un oneliner commeIFS=$'\n' for l in lines; do ... done
drevicko
31

Juste mettre

export HOME=/blah/whatever

au point du script où vous souhaitez que le changement se produise. Étant donné que chaque processus a son propre ensemble de variables d'environnement, cette définition cessera automatiquement d'avoir toute signification lorsque le script se terminera (et avec elle l'instance de bash qui a un environnement modifié).

Hmakholm a laissé Monica
la source
11
C'est trompeur. exportpassera la variable aux sous-shell, mais il ne contrôle pas le shell parent. Si vous écrivez un script qui commence par "#! / Bin / sh" ou autre, TOUTE variable que vous définissez disparaîtra lorsque le script se terminera.
brightlancer
1
@brightlancer, c'est vrai mais ne semble pas contredire ce que j'ai écrit. (À l'exception de la possibilité que le script puisse démarrer un processus d'arrière-plan, mais je pense que cela dépasse le niveau de sophistication de l'OP et ne ferait que semer la confusion).
hmakholm a quitté Monica
5
L'exportation n'est pas nécessaire. De plus, votre réponse ne fonctionne que si son script invoque un interpréteur (#! / Bin / sh ou autre). Si son "script" ne le fait pas, alors ce que vous venez de lui dire persistera au-delà de la fin de son script. C’est la raison pour laquelle j’ai dit que votre réponse était trompeuse - elle était peut-être correcte, peut-être pas, mais elle contient certainement une partie qui est inutile et déroutante, car cela peut amener quelqu'un à penser que «l’exportation» est l’élément nécessaire qu’il recherchait.
brightlancer
7
@brightlancer: L'export est nécessaire si le script de l'OP invoque des sous-scripts qui dépendent eux-mêmes de $ HOME, et je n'osais pas supposer que ce n'était pas le cas. De plus, bash créera un sous-shell pour exécuter un script même si le script n'a pas de ligne shebang mais est juste un fichier texte avec le bit d'exécution défini. Essayez-le - les affectations de variables dans le script ne sont pas visibles dans le shell à partir duquel vous l'appelez. Ce n'est que si vous explicitement sourcele script qu'il sera exécuté par le même shell dans lequel vous tapez la commande.
hmakholm a quitté Monica
4
@brightlancer: L'export est nécessaire s'il veut $HOMEêtre hérité par les commandes exécutées à partir du script. Et s'il ne le fait pas, et que le paramétrage de $HOMEn'est que pour le bénéfice du script lui-même, alors il ferait probablement mieux de modifier le script pour qu'il se réfère à autre chose que $HOME.
Keith Thompson