Frage

Ich glaube, dass mit einer leicht veränderten Umgebung einen externen Befehl ausgeführt wird ein sehr verbreiteter Fall ist. Das ist, wie ich neige dazu, es zu tun:

import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)

Ich habe ein gut Gefühl, dass es ein besserer Weg ist; sieht es in Ordnung?

War es hilfreich?

Lösung

Ich denke, os.environ.copy() besser ist, wenn Sie nicht beabsichtigen, die os.environ für den aktuellen Prozess zu ändern:

import subprocess, os
my_env = os.environ.copy()
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)

Andere Tipps

Das hängt davon ab, was das Problem ist. Wenn es zu klonen ist und ändern könnte die Umwelt eine Lösung sein:

subprocess.Popen(my_command, env=dict(os.environ, PATH="path"))

Aber das etwas davon abhängt, dass die ersetzten Variablen gelten Python-Kennungen, die sie am häufigsten sind (wie oft laufen Sie in Umgebungsvariablen, die nicht alphanumerische + Strich oder Variablen, die beginnt mit einer Reihe sind?).

Sonst wirst du etwas schreiben könnte wie:

subprocess.Popen(my_command, env=dict(os.environ, 
                                      **{"Not valid python name":"value"}))

In dem sehr seltsam Fall (wie so häufig verwenden Sie Steuercodes oder Nicht-ASCII-Zeichen in Umgebungsvariablen?), Dass die Schlüssel der Umwelt sind bytes können Sie nicht (auf python3) selbst, dass Konstrukt verwenden.

Wie Sie die Techniken sehen können (vor allem die erste) verwendet hier Vorteile auf den Tasten der Umwelt normalerweise gilt Python Identifikatoren, und auch im Voraus (bei Codierung Zeit) bekannt ist, hat der zweite Ansatz Probleme. In Fällen, in denen dies nicht der Fall ist, dass Sie wahrscheinlich für ein weiterer Ansatz .

Sie könnten my_env.get("PATH", '') statt my_env["PATH"] bei PATH verwenden irgendwie nicht in der ursprünglichen Umgebung definiert, aber außer, dass es gut aussieht.

Mit Python 3.5 Sie könnte es auf diese Weise tun:

import os
import subprocess

my_env = {**os.environ, 'PATH': '/usr/sbin:/sbin:' + os.environ['PATH']}

subprocess.Popen(my_command, env=my_env)

wir hier mit einer Kopie os.environ und außer Kraft gesetzt PATH Wert am Ende.

Es wurde möglich durch PEP 448 (Zusätzliche Auspacken Verallgemeinerungen).

Ein weiteres Beispiel. Wenn Sie eine Standardumgebung (das heißt os.environ) haben, und ein dict möchten Sie Standardwerte mit außer Kraft zu setzen, können Sie es so ausdrücken:

my_env = {**os.environ, **dict_with_env_variables}

Um vorübergehend eine Umgebungsvariable gesetzt, ohne das os.environ Objekt etc kopieren zu müssen, ich dies tun:

process = subprocess.Popen(['env', 'RSYNC_PASSWORD=foobar', 'rsync', \
'rsync://username@foobar.com::'], stdout=subprocess.PIPE)

Die env-Parameter akzeptieren ein Wörterbuch. Sie können einfach nehmen os.environ, einen Schlüssel (Ihre gewünschte Variable) (auf eine Kopie des dict, wenn Sie müssen) ergänzen, dass es als Parameter an Popen verwenden.

Ich weiß, das ist schon seit einiger Zeit beantwortet, aber es gibt einige Punkte, die einige möchten vielleicht über die Verwendung von PYTHONPATH anstelle von PATH in ihrer Umgebungsvariable kennen. Ich habe eine Erklärung der laufenden Python-Skripte mit Cronjobs, dass befasst sich mit der veränderten Umwelt auf andere Weise skizziert ( hier gefunden ). Dachte, es von einigen gut für diejenigen, die, wie ich gebraucht wäre, nur ein wenig mehr als diese Antwort zur Verfügung gestellt.

Unter bestimmten Umständen möchten Sie dürfen nur an die Umgebungsvariablen Ihre subprocess Bedürfnisse weitergeben, aber ich denke, Sie in der Regel richtige Idee haben (das ist, wie ich es auch tun).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top