wie kann ich einen Kindprozess "belauschen"

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
thomst
User
Beiträge: 13
Registriert: Montag 26. April 2010, 18:40

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
Benutzeravatar
snafu
User
Beiträge: 6851
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
thomst
User
Beiträge: 13
Registriert: Montag 26. April 2010, 18:40

blockiert leider auch...
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.
thomst
User
Beiträge: 13
Registriert: Montag 26. April 2010, 18:40

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.
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.
thomst
User
Beiträge: 13
Registriert: Montag 26. April 2010, 18:40

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
Antworten