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:

  • Führen Sie das Python-Skript nach dem anderen aus
  • Wie bekomme ich jede Prozess-ID beim Multiprocessing
  • Holen Sie sich den Prozessnamen von PID
  • Python: Wie bekomme ich PID nach Prozessnamen?
  • Kannst du Code / eine Exe in einen Prozess mit Python injizieren?
  • Warten Sie, bis ein bestimmter Prozess (das "pid") endet
  • 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?

  • Python eval: Ist es immer noch gefährlich, wenn ich die Baustellen und den Attributzugriff deaktiviere?
  • Verwendung von eval in Python?
  • Wie kann man einen String mit einem gleichen Symbol auswerten?
  • Den Zugriff auf das Dateisystem in exec und eval in Python nicht zulassen
  • Was sind gültige Aussagen in einer Python-Eval ()?
  • CNTK python API: Wie bekomme ich Prognosen aus dem trainierten Modell?
  • 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.