Je crois que l'exécution d'une commande externe avec un environnement légèrement modifié est un cas très courant. Voilà comment j'ai tendance à le faire:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
J'ai l'intuition qu'il y a une meilleure façon; ça a l'air bien?
python
subprocess
popen
Oren_H
la source
la source
os.pathsep
au lieu de ":" pour les chemins d'accès qui fonctionnent sur plusieurs plateformes. Voir stackoverflow.com/questions/1499019/.../usr/sbin
:-)Réponses:
Je pense que
os.environ.copy()
c'est mieux si vous n'avez pas l'intention de modifier os.environ pour le processus actuel:la source
os.environ.copy
à laenv
variable mais vous devez affecter le résultat de l'appel de la méthodeos.environ.copy()
àenv
.shell=True
dans votresubprocess.Popen
appel. Notez que cela peut potentiellement impliquer des problèmes de sécurité.my_command
est juste une commande à exécuter. Il peut s'agir par exemple/path/to/your/own/program
ou de toute autre instruction "exécutable".Cela dépend du problème. Pour cloner et modifier l'environnement, une solution pourrait être:
Mais cela dépend quelque peu du fait que les variables remplacées sont des identificateurs python valides, ce qu'elles sont le plus souvent (à quelle fréquence rencontrez-vous des noms de variables d'environnement qui ne sont pas alphanumériques + trait de soulignement ou des variables qui commencent par un nombre?).
Sinon, vous pourriez écrire quelque chose comme:
Dans le cas très étrange (à quelle fréquence utilisez-vous des codes de contrôle ou des caractères non-ascii dans les noms de variables d'environnement?) Que les clés de l'environnement ne sont
bytes
pas vous (sur python3) même utiliser cette construction.Comme vous pouvez voir les techniques (en particulier la première) utilisées ici, les avantages sur les clés de l'environnement sont normalement des identifiants python valides, et également connus à l'avance (au moment du codage), la deuxième approche a des problèmes. Dans les cas où ce n'est pas le cas, vous devriez probablement chercher une autre approche .
la source
dict(mapping, **kwargs)
. Je pensais que c'était soit ou. Remarque: il copieos.environ
sans le modifier comme l'a suggéré @Daniel Burke dans la réponse actuellement acceptée, mais votre réponse est plus succincte. En Python 3.5+, vous pourriez même le fairedict(**{'x': 1}, y=2, **{'z': 3})
. Voir pep 448 .vous pouvez utiliser
my_env.get("PATH", '')
au lieu demy_env["PATH"]
dans le cas oùPATH
non défini dans l'environnement d'origine, mais à part cela, cela semble bien.la source
Avec Python 3.5, vous pouvez le faire de cette façon:
Ici, nous nous retrouvons avec une copie de
os.environ
et unePATH
valeur remplacée .Il a été rendu possible par le PEP 448 (Générations de déballage supplémentaires).
Un autre exemple. Si vous avez un environnement par défaut (c.-à-d.
os.environ
) Et un dict avec lequel vous souhaitez remplacer les valeurs par défaut, vous pouvez l'exprimer comme ceci:la source
Pour définir temporairement une variable d'environnement sans avoir à copier l'objet os.envrion, etc., je fais ceci:
la source
Le paramètre env accepte un dictionnaire. Vous pouvez simplement prendre os.environ, ajouter une clé (votre variable souhaitée) (à une copie du dict si vous le devez) et l'utiliser comme paramètre pour
Popen
.la source
os.environ['SOMEVAR'] = 'SOMEVAL'
Je sais que cela a été répondu depuis un certain temps, mais il y a certains points que certains voudront peut-être savoir sur l'utilisation de PYTHONPATH au lieu de PATH dans leur variable d'environnement. J'ai décrit une explication de l'exécution de scripts python avec cronjobs qui traite l'environnement modifié d'une manière différente ( trouvée ici ). Je pensais que ce serait quelque chose de bon pour ceux qui, comme moi, avaient besoin d'un peu plus que cette réponse.
la source
Dans certaines circonstances, vous souhaiterez peut-être transmettre uniquement les variables d'environnement dont votre sous-processus a besoin, mais je pense que vous avez la bonne idée en général (c'est comme ça que je le fais aussi).
la source