Ich glaube, dass das Ausführen eines externen Befehls in einer leicht geänderten Umgebung ein sehr häufiger Fall ist. So mache ich das:
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 das Gefühl, dass es einen besseren Weg gibt. sieht es gut aus
python
subprocess
popen
Oren_H
quelle
quelle
os.pathsep
anstelle von ":" auch Pfade, die plattformübergreifend funktionieren. Siehe stackoverflow.com/questions/1499019/…/usr/sbin
:-)Antworten:
Ich denke, es
os.environ.copy()
ist besser, wenn Sie nicht beabsichtigen, die os.environ für den aktuellen Prozess zu ändern:quelle
os.environ.copy
zu derenv
Variable , aber Sie müssen das Ergebnis der Aufruf der Methode zuweisenos.environ.copy()
zuenv
.shell=True
in Ihremsubprocess.Popen
Aufruf verwenden. Beachten Sie, dass dies möglicherweise Auswirkungen auf die Sicherheit hat.my_command
ist nur ein Befehl zum Ausführen. Dies kann beispielsweise/path/to/your/own/program
eine andere "ausführbare" Anweisung sein.Das hängt davon ab, worum es geht. Wenn die Umgebung geklont und geändert werden soll, könnte eine Lösung sein:
Dies hängt jedoch etwas davon ab, dass die ersetzten Variablen gültige Python-Bezeichner sind, die sie am häufigsten sind (wie oft stoßen Sie auf Umgebungsvariablennamen, die nicht alphanumerisch + unterstrichen sind, oder auf Variablen, die mit einer Zahl beginnen?).
Andernfalls könnten Sie etwas schreiben wie:
In dem sehr seltsamen Fall (wie oft verwenden Sie Steuercodes oder Nicht-ASCII-Zeichen in Umgebungsvariablennamen?), Dass die Schlüssel der Umgebung sind
bytes
, können Sie (auf Python3) dieses Konstrukt nicht einmal verwenden.Wie Sie sehen können, sind die Techniken (insbesondere die erste), die hier für die Schlüssel der Umgebung verwendet werden, normalerweise gültige Python-Kennungen, und auch im Voraus (zum Codierungszeitpunkt) bekannt. Der zweite Ansatz weist Probleme auf. In Fällen, in denen dies nicht der Fall ist, sollten Sie wahrscheinlich nach einem anderen Ansatz suchen .
quelle
dict(mapping, **kwargs)
. Ich dachte es wäre entweder oder. Hinweis: Es wird kopiert,os.environ
ohne es zu ändern, wie es @Daniel Burke in der aktuell akzeptierten Antwort vorgeschlagen hat, aber Ihre Antwort ist prägnanter. In Python 3.5+ können Sie dies sogar tundict(**{'x': 1}, y=2, **{'z': 3})
. Siehe S. 448 .Sie können
my_env.get("PATH", '')
anstelle vonmy_env["PATH"]
für den Fall verwendenPATH
, dass es in der ursprünglichen Umgebung nicht definiert ist, aber ansonsten sieht es gut aus.quelle
Mit Python 3.5 können Sie dies folgendermaßen tun:
Hier erhalten wir eine Kopie des
os.environ
überschriebenenPATH
Werts.Möglich wurde dies durch PEP 448 (Additional Unpacking Generalizations).
Ein anderes Beispiel. Wenn Sie eine Standardumgebung (dh
os.environ
) und ein Diktat haben, mit dem Sie die Standardeinstellungen überschreiben möchten, können Sie dies folgendermaßen ausdrücken:quelle
Um eine Umgebungsvariable vorübergehend festzulegen, ohne das Objekt os.envrion usw. kopieren zu müssen, gehe ich folgendermaßen vor:
quelle
Der Parameter env akzeptiert ein Wörterbuch. Sie können einfach os.environ nehmen, einen Schlüssel (Ihre gewünschte Variable) (zu einer Kopie des Diktats, wenn Sie müssen) hinzufügen und ihn als Parameter für verwenden
Popen
.quelle
os.environ['SOMEVAR'] = 'SOMEVAL'
Ich weiß, dass dies seit einiger Zeit beantwortet wurde, aber es gibt einige Punkte, die einige über die Verwendung von PYTHONPATH anstelle von PATH in ihrer Umgebungsvariablen wissen möchten. Ich habe eine Erklärung zum Ausführen von Python-Skripten mit Cronjobs skizziert, die die geänderte Umgebung auf andere Weise behandelt ( hier zu finden ). Ich dachte, es wäre etwas Gutes für diejenigen, die wie ich nur ein bisschen mehr brauchten als diese Antwort.
quelle
Unter bestimmten Umständen möchten Sie möglicherweise nur die Umgebungsvariablen weitergeben, die Ihr Unterprozess benötigt, aber ich denke, Sie haben im Allgemeinen die richtige Idee (so mache ich das auch).
quelle