Seite 1 von 1

wie kann ich einen Kindprozess "belauschen"

Verfasst: Freitag 30. September 2011, 14:21
von thomst
Hi,
Also: ich starte in meinem Skript einen Kindprozess, der eine potentiell unendliche Laufzeit hat, und möchte während dieser Laufzeit dessen stdout und stderr "belauschen", und ihm obendrein inputs geben.
Meine Ansätze bisher arbeiten mit subprocess.communicate oder indem ich auf subprocess.stdout.read() als FileObjekt zugreife. Leider friert beides mein Skript ein, da jeweils auf die Beendigung des Kindprozesses gewartet wird.

Das erste Code-Gerüst ist folgendes (ohne subprocess.communicate ect.):

Code: Alles auswählen

import os, subprocess, shlex, time, sys, logging
from subprocess import PIPE, check_call

t = 0
logging.basicConfig(
	filename='/home/thomas/gphoto_test/gphoto.log',
	level=logging.INFO,
	filemode='w',
	format='%(asctime)s:%(levelname)s:%(message)s'
)

args = shlex.split("/home/thomas/gphoto_test/test.py")

def start_process(args):
	try:
		p = subprocess.Popen(args,
			stdin=PIPE,
			stdout=PIPE,
			stderr=PIPE,
			cwd='/home/thomas/gphoto_test',
		)
	except subprocess.CalledProcessError as (bla):
		logging.error('CalledProcessError: {0}'.format(bla))
	except OSError as (errorno, errorstr):
		logging.error("OSError({0}): {1}".format(errorno, errorstr))
	except ValueError as (errorno, errorstr):
		logging.error("ValueError({0}): {1}".format(errorno, errorstr))
	except:
		logging.error("Unexpected error:", sys.exc_info()[0])
		raise
	return p

while 1:
	if time.time()-t >= 2:
		if not t: p = start_process(args)
		t = time.time()

Die Idee dahinter ist, innerhalb der while-Schleife alle Aktionen sowie das Belauschen des Kindprozesses zu implementieren. Ist das ein brauchbarer Ansatz?

Für Hilfe und Anregungen wäre ich sehr dankbar...
Thomas

Re: wie kann ich einen Kindprozess "belauschen"

Verfasst: Freitag 30. September 2011, 14:33
von snafu
Probiere mal aus, was passiert, wenn du anstatt dem `stdout.read()` ein `stdout.readline()` benutzt...

Ansonsten guck dir das 3rd-Party Modul `pexpect` mal an.

Re: wie kann ich einen Kindprozess "belauschen"

Verfasst: Freitag 30. September 2011, 14:37
von thomst
blockiert leider auch...

Re: wie kann ich einen Kindprozess "belauschen"

Verfasst: Freitag 30. September 2011, 14:49
von lunar
Nutze "select", um darauf zu warten, dass der Prozess etwas in die Pipe schreibt, und lese den Inhalt der Pipe dann mit ".readline()" aus.

Re: wie kann ich einen Kindprozess "belauschen"

Verfasst: Freitag 30. September 2011, 15:48
von thomst
lunar hat geschrieben:Nutze "select", um darauf zu warten, dass der Prozess etwas in die Pipe schreibt, und lese den Inhalt der Pipe dann mit ".readline()" aus
jo...
also wie genau benutze ich select?
Hab es folgendermaßen probiert:

Code: Alles auswählen

while 1:
	if time.time()-t >= 2:
		if not t: p = start_process(args)
		t = time.time()

		select([p.stdout], [], [])
		print p.stdout.readline()
Fehlermeldung:

Code: Alles auswählen

  File "/home/thomas/bin/gphoto2-ctrl.py", line 41, in <module>
    select([p.stdout], [], [])
TypeError: argument must be an int, or have a fileno() method.
edit: ok. Fehlermeldung kam weil ich für stdout des Kindprozesses die PIPE nicht angegeben hatte. Dennoch bleibt das Problem, dass die while Schleife blockiert wird.

Re: wie kann ich einen Kindprozess "belauschen"

Verfasst: Freitag 30. September 2011, 19:21
von lunar
@thomst: Lies die Dokumentation zu "select()". Aus dieser geht hervor, dass die Funktion einen Rückgabewert hat, welchen Du selbstverständlich auswerten musst. Ferner ist ihr zu entnehmen, dass "select()" blockiert, sofern Du keinen "timeout" angibst.

Re: wie kann ich einen Kindprozess "belauschen"

Verfasst: Montag 10. Oktober 2011, 11:03
von thomst
lunar hat geschrieben:@thomst: Lies die Dokumentation zu "select()". Aus dieser geht hervor, dass die Funktion einen Rückgabewert hat, welchen Du selbstverständlich auswerten musst. Ferner ist ihr zu entnehmen, dass "select()" blockiert, sofern Du keinen "timeout" angibst.
Ok. Danke für die Hinweise und Antworten.
Es hat sich allerdings ergeben, dass ich wohl doch ohne Probleme auf die Antwort des Child-Prozesses warten kann. Somit ist (für dieses Projekt zumindest) select wohl nicht von Nöten. Wenn ich es mal brauchen werde, schaue ich mir die Dokumentation genauer an...

Danke,
Thomas