Je rencontre un problème avec la définition d'une variable d'environnement lors d'un appel à subprocess.Popen
. La variable d'environnement ne semble pas être définie. Des suggestions sur la façon de définir correctement les variables d'environnement pour un appel en ligne de commande Python?
Mon objectif est d'exécuter un script qui utilise une variable d'environnement déterminée à partir de mon code Python:
d = dict(os.environ)
d["TEST_VARIABLE"] = str(1234)
subprocess.Popen('/usr/bin/mybinary', env=d).wait()
mais le script réagit comme si la variable n'avait jamais été définie
Voici ma tentative de test, en utilisant l'interpréteur interactif de Python:
d = dict(os.environ)
d["TEST_VARIABLE"] = str(1234)
subprocess.Popen(['/bin/echo', '$TEST_VARIABLE'], env=d).wait()
et la sortie est:
"$TEST_VARIABLE"
0
J'ai pensé env=d
devrait définir l'environnement du sous-processus, mais ce n'est apparemment pas le cas. Des suggestions sur la façon de corriger ce problème?
La substitution des variables d'environnement sur la ligne de commande est effectuée par le Shell, pas par/bin/echo. Vous devez donc exécuter la commande dans un shell pour obtenir la substitution:
In [22]: subprocess.Popen('/bin/echo $TEST_VARIABLE', Shell=True, env=d).wait()
1234
Out[22]: 0
Cela ne signifie pas que la variable d'environnement n'est pas définie lorsque Shell=False
, pourtant. Même sans Shell=True
, l'exécutable voit les variables d'environnement définies par le paramètre env
. Par exemple, date
est affecté par la variable d'environnement TZ
:
In [23]: subprocess.Popen(["date"], env={'TZ': 'America/New_York'}).wait()
Wed Oct 29 22:05:52 EDT 2014
Out[23]: 0
In [24]: subprocess.Popen(["date"], env={'TZ': 'Asia/Taipei'}).wait()
Thu Oct 30 10:06:05 CST 2014
Out[24]: 0
Pour Python 3.5 et plus récent, vous pouvez utiliser décompresser les généralisations , par exemple:
env = {
**os.environ,
"TEST_VARIABLE": str(1234),
}
subprocess.Popen('/usr/bin/mybinary', env=env).wait()
Vous devez utiliser os.environ.copy()
pour le faire fonctionner. Il crée une copie de l'ensemble du dictionnaire d'environnement que vous pouvez ensuite modifier avant de le transmettre au sous-processus, sans modifier l'environnement de processus actuel.
Voir cette réponse .