Wie bekomme ich PID über subprocess.Popen mit benutzerdefinierter Umgebungsvariable?

Mit Python, wie kann ich einen Teilprozess mit einer modifizierten Umgebungsvariablen ausführen und seine PID erhalten? Ich nehme subprocess.Popen () ist auf dem richtigen Weg …

In der Schale (bash) würde ich das tun:

MY_ENV_VAR=value ./program_name arg1 arg2 etc & 

Hierbei handelt es sich um den program_name im Hintergrund, wobei "arg1" und "arg2" und "etc" mit einer modifizierten Umgebungsvariablen "MY_ENV_VAR" mit einem Wert von "value" übergeben werden. Der Programm program_name erfordert, dass die Umgebungsvariable MY_ENV_VAR auf den richtigen Wert gesetzt wird.

Wie kann die gleichwertige Sache in Python? Ich brauche unbedingt die PID des Prozesses. (Meine Absicht ist, das Python-Skript zu laufen und die Durchführung von Checks auf einige der Dinge, die program_name in der Zwischenzeit tut, und ich brauche die Prozess-ID, um sicherzustellen, dass es noch läuft.)

Ich habe es versucht:

 proc = subprocess.Popen(['MY_ENV_VAR=value', './program_name', 'arg1', 'arg2', 'etc']) 

Aber natürlich erwartet es das erste Element, das Programm zu sein, nicht eine Umgebungsvariable.

Auch versucht:

 environ = dict(os.environ) environ['MY_ENV_VAR'] = 'value' proc = subprocess.Popen(['./program_name', 'arg1', 'arg2', 'etc', env=environ]) 

Schließe ich, aber keine zigarre Ähnlich:

 environ = dict(os.environ) environ['MY_ENV_VAR'] = 'value' proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ) 

Das sagt echt "$ MY_ENV_VAR" wörtlich, ich vermute, weil es keine Shell gibt, um es zu interpretieren. Okay, also versuche ich das oben, aber mit dieser Zeile stattdessen:

 proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ, shell=True) 

Und das ist gut und dandy, außer dass der Wert, der widerhallt, leer ist (scheint nicht anscheinend). Und selbst wenn es funktionierte, würde ich die PID der Shell bekommen, nicht den eigentlichen Prozess, den ich versuche zu starten.

Ich muss einen Prozess mit einer benutzerdefinierten Umgebungsvariable starten und seine PID (nicht die PID der Shell) bekommen. Ideen?

  • Erhalten Sie rezessive Unterprozesse
  • Start nano als Teilprozeß von python, capture input
  • Beenden eines Programms innerhalb eines Zeitrahmens durch Python
  • Subprocess.Popen () hat ein inkonsistentes Verhalten zwischen Eclipse / PyCharm und Terminalausführung
  • So öffnen Sie eine Datei auf Mac OSX 10.8.2 in Python
  • Popen Fehler: [Errno 2] Keine solche Datei oder Verzeichnis
  • Wie kann ich subprocess.Popen () fehlschlagen, wenn shell = True
  • Python-Subprocess-Popen inkonsistentes Verhalten in einer Multi-Thread-Umgebung
  • 2 Solutions collect form web for “Wie bekomme ich PID über subprocess.Popen mit benutzerdefinierter Umgebungsvariable?”

    Ihre letzte Version ist sehr nah, aber nicht ganz da.

    Sie wollen nicht, dass $MY_ENV_VAR ein Argument zum echo . Das echo Programm hat MY_ENV_VAR in seiner Umgebung, aber echo macht keine env variable Erweiterung. Du brauchst es, um durch die Schale erweitert zu werden, bevor es sogar zum echo .

    Das kann eigentlich nichts mit deinem echten Testfall zu tun haben. Sie bekommen bereits die Umgebungsvariable für den Kind-Prozess in all Ihren Tests, es ist nur, dass echo nichts mit dieser Umgebungsvariable macht. Wenn Ihr echtes Programm nur die Umgebungsvariable benötigt, um eingestellt zu werden, sind Sie fertig:

     proc = subprocess.Popen(['./program_name', 'arg1', 'arg2', 'etc'], env=environ) 

    Aber wenn dein Programm es braucht, um ersetzt zu werden, wie echo , dann musst du es in die Argumente ersetzen, bevor sie an dein Programm übergeben werden.

    Der einfachste Weg, dies zu tun ist, geben Sie einfach die Shell eine Kommandozeile anstelle einer Liste von Argumenten:

     proc = subprocess.Popen('echo "$MY_ENV_VAR"', env=environ, shell=True) 

    Die Leute werden Ihnen sagen, dass Sie nie eine Befehlszeichenfolge in subprocess – aber der Grund dafür ist, dass Sie immer die Shell daran hindern möchten, Variablen usw. zu erweitern, und zwar so, dass es unsicher wäre. Bei den seltenen Gelegenheiten, wenn du die Shell dazu veranlassen willst, willst du eine Befehlszeichenfolge.

    Natürlich, wenn Sie eine Shell verwenden, auf den meisten Plattformen, werden Sie am Ende bekommen die PID der Shell statt der PID des eigentlichen Programms. Kurz, einige plattformspezifische Grabungen zu machen, um die Kinder der Muschel aufzuzählen (oder das Ganze in irgendeinem einfachen sh Code zu verpacken, das dir die PID des Kindes indirekt gibt), gibt es keine Möglichkeit, dass. Die Shell ist was du laufst.

    Eine andere Alternative ist, die Variablen in Python zu erweitern, anstatt die Shell zu machen. Dann brauchst du nicht mal eine Schale:

     proc = subprocess.Popen(['echo', os.path.expandvars('$MY_ENV_VAR')]) 

    … oder noch einfacher:

     proc = subprocess.Popen(['echo', os.environ['MY_ENV_VAR']]) 

    Hier ist ein Programm, das die aktuelle Umgebung ausspuckt.

     #!/usr/bin/env python ##program_name import os for k,v in os.environ.iteritems(): print k, '=', v 

    Hier ist ein Programm, das das andere Programm anruft, aber zuerst die Umgebung ändert

     #!/usr/bin/env python import subprocess, os newenv = os.environ.copy() newenv['MY_ENV_VAR'] = 'value' args = ['./program_name', 'arg1', 'arg2', 'etc'] proc = subprocess.Popen(args, env=newenv) pid = proc.pid proc.wait() print 'PID =', pid 
    Python ist die beste Programmiersprache der Welt.