Wie man PID über Teilprozess.Popen mit benutzerdefinierten Umgebungsvariablen?
Mithilfe von Python, wie kann ich einen Teilprozess mit einem geänderten Umgebungsvariablen und Holen Sie sich die PID? Ich gehe davon aus Teilprozess.Popen() ist auf der rechten Spur...
In der shell (bash), würde ich dies tun:
MY_ENV_VAR=value ./program_name arg1 arg2 etc &
Läuft program_name
im hintergrund, übergehend in "arg1" und "arg2" und "etc", mit einer geänderten Umgebungsvariablen "MY_ENV_VAR" mit dem Wert "Wert". Das Programm program_name
erfordert die Umgebungsvariable MY_ENV_VAR
festgelegt werden, um den korrekten Wert.
Wie kann das gleiche Ding in Python? Ich brauche unbedingt die PID des Prozesses. (Meine Absicht ist es, halten Sie das python-Skript ausgeführt und Prüfungen auf einige der Dinge, die program_name
ist zu tun in der Zwischenzeit, und ich brauche die Prozess-ID, um sicherzustellen, dass es immer noch läuft.)
Ich versucht habe:
proc = subprocess.Popen(['MY_ENV_VAR=value', './program_name', 'arg1', 'arg2', 'etc'])
Aber natürlich, es erwartet, dass die ersten Artikel auf das Programm, nicht eine Umgebungsvariable.
Habe auch versucht:
environ = dict(os.environ)
environ['MY_ENV_VAR'] = 'value'
proc = subprocess.Popen(['./program_name', 'arg1', 'arg2', 'etc', env=environ])
Schließen, nehme ich an, aber keine Zigarre. Ähnlich:
environ = dict(os.environ)
environ['MY_ENV_VAR'] = 'value'
proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ)
Dieser echo "$MY_ENV_VAR" wörtlich, ich nehme an, weil es keine shell zu interpretieren. Okay, also ich versuchen, die oben, aber mit dieser Zeile statt:
proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ, shell=True)
Und das ist schön und gut, außer, dass der Wert, der echo ist leer (nicht scheinbar vorhanden ist). Und selbst wenn es funktioniert hat, würd ich bekomme die PID der shell, nicht den eigentlichen Prozess, den ich versuche zu starten.
Brauche ich, um einen Prozess einzuleiten, mit dem eine benutzerdefinierte Umgebungsvariable und Holen Sie sich die PID (nicht die PID der shell). Ideen?
Ich brauche nur die Schale, soweit das setzen/übergeben Sie die Umgebungsvariable für diesen Prozess geht. Wenn ich nicht brauchen, die shell, die ich lieber nicht verwenden. (Aber ich brauche Argumente, um das Programm und haben es im hintergrund laufen.)
Die environment-Variablen übergeben werden, um den Teilprozess in Ihrer
proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ)
Beispiel; Teilprozess, dass einfach nicht alles tun, um Ihnen zu zeigen, dass Sie sind, weil echo schaut nie auf seine Umwelt. Versuchen subprocess.Popen(['env'], env=environ)
statt.D ' Oh! Das ist es. Sie und abarnet habe es mir etwa zur gleichen Zeit.
Übrigens, wenn Sie das "echte Programm" PID bei Verwendung
shell=True
(die, wieder, Sie sollten nicht immer verwenden, es sei denn, Sie wirklich wissen, was Sie tun), können Sie tun, indem Sie das shell-Skript aufrufen, der Letzte Befehl mit exec
. Für dieses Beispiel: exec echo "$MY_ENV_VAR"
; dies bewirkt, dass der echo-Befehl ersetzt den shell-Prozess erbt die PID.InformationsquelleAutor Matt | 2013-04-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Deine Letzte version ist sehr nah, aber nicht ganz da.
Wollen Sie nicht
$MY_ENV_VAR
ein argument zu sein, umecho
. Dieecho
ProgrammMY_ENV_VAR
in seiner Umgebung, aberecho
nicht im env-variable expansion. Sie müssen erweitert werden, indem die shell, noch bevor Sie bekommtecho
.Kann dies eigentlich nichts zu tun haben, mit Ihrer real-life-test-Fall. Sie bereits sind immer die environment-variable wird der Kind-Prozess in alle Ihre tests, es ist nur so, dass
echo
nichts mit, dass die environment-variable. Wenn Ihr richtiges Programm muss nur die environment-variable gesetzt werden, sind Sie fertig:Aber wenn dein Programm muss es sein ersetzt, wie
echo
, dann haben Sie zu ersetzen, es in die Argumente vor Sie weitergeleitet zu Ihrem Programm.Der einfachste Weg, dies zu tun, ist nur eben der shell einen Befehl in der Befehlszeile anstelle von einer Liste von Argumenten:
Leute werden Ihnen sagen, Sie sollten niemals ein Kommando-string in
subprocess
—aber der Grund dafür ist, dass Sie immer wollen, um zu verhindern, dass die shell expandiert Variablen, etc., in einer Weise, die sein könnte, unsicher/etc. Bei den seltenen Gelegenheiten, wenn Sie wollen der shell zu tun, seine shelly Dinge, die Sie wollen ein Kommando-string.Natürlich, wenn Sie eine shell, die auf den meisten Plattformen, wirst du am Ende immer die PID der shell, anstatt die PID des aktuellen Programms. Kurz zu tun, einige Plattform-spezifische Graben zum auflisten der shell-Kinder (oder wickelt das ganze in ein paar einfachen
sh
code, gibt Sie das Kind der PID-indirekt), es gibt keinen Weg darum herum. Die shell ist das, was Sie sind.Andere alternative ist der ausbau der Variablen in Python statt der shell, tun es. Dann brauchen Sie sich nicht einmal müssen shell:
... oder, noch einfacher:
'echo "$MY_ENV_VAR"'
, bitte-andernfalls wird die variable s Inhalt string-split und glob-erweitert.Cool, das (erste) funktioniert, und ich verstehe jetzt, warum-aber ich bekomme die PID der shell (sh) anstelle der echo-Prozess. Für den ausbau der variable mit Python, das ist eine gute Idee, aber ich war wohl nicht klar: das Programm, das aufgerufen wird erwartet, dass Umgebungsvariable gesetzt sein, ich kann nicht einfach übergeben es als argument.
Sie können Lesen, eine ältere version der Antwort. Um die Umgebungsvariable , sondern als ersetzt, verwenden Sie einfach die
env
parameter, und nicht die shell auf alle. Der einzige Grund, warum das nicht funktioniert in Ihremecho
tests ist, dass echo muss die variable ersetzt werden, nicht festgelegt.Du hast Recht. Ich habe Ihre Antwort aktualisiert und Charles' Kommentar bei der gleichen Zeit. Dies scheint den trick tun. Danke! Ich wusste gar nicht, dass die Umwelt übergeben wurde, direkt in das Programm statt des shell - (na toll, auf meinem Teil).
InformationsquelleAutor abarnert
hier ist ein Programm, das spuckt die aktuelle Umgebung.
Hier ist ein Programm, das fordert das andere Programm, aber erste Veränderungen der Umwelt
{k:v for k,v in anything.iteritems()}
statt nurdict(anything)
?Ich war nicht denken, es durch.
InformationsquelleAutor Hal Canary