Daten an Subprocess übergeben bzw. im Subprocess auslesen ?

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.
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Beitragvon modelnine » Mittwoch 18. Januar 2006, 12:13

Möglichkeit 1 ist das richtige. ;-)

Die Dokumentation vom subprocess-Modul müßte den Rest erklären.

--- Heiko.
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Mittwoch 18. Januar 2006, 22:10

modelnine hat geschrieben:Möglichkeit 1 ist das richtige. ;-)
--- Heiko.


Ahhh ! Bin ich ja doch schonmal ein bischen weiter :D
Dennoch verstehe ich dann nicht, wieso mir dieses Minibeispiel

Code: Alles auswählen

#Daten an Subprozess schicken
import subprocess
p = subprocess.Popen('C:/Ablage/Python/PythonScripte/test.py',stdin = subprocess.PIPE)
raus = "10" + "20" + "Fred vom Jupiter"
p.stdin.write(raus)
p.close()


folgende Fehlermeldungen erzeugt:

[code=]Traceback (most recent call last):
File "C:\Ablage\Python\PythonScripte\test2.py", line 3, in -toplevel-
p = subprocess.Popen('C:/Ablage/Python/PythonScripte/test.py',stdin = subprocess.PIPE)
File "C:\Programme\Python24\lib\subprocess.py", line 533, in __init__
(p2cread, p2cwrite,
File "C:\Programme\Python24\lib\subprocess.py", line 607, in _get_handles
c2pwrite = self._make_inheritable(c2pwrite)
File "C:\Programme\Python24\lib\subprocess.py", line 634, in _make_inheritable
DUPLICATE_SAME_ACCESS)
WindowsError: [Errno 6] Das Handle ist ungültig[/code]

Und dieses Beispiel bemängelt der Interpreter auch:

Code: Alles auswählen

#übergebene Daten auslesen
import sys
print sys.stdout.read()


[code=]Traceback (most recent call last):
File "C:\Ablage\Python\PythonScripte\test.py", line 2, in -toplevel-
print sys.stdout.read()
AttributeError: read[/code]

Gruss, Seven
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Donnerstag 19. Januar 2006, 07:38

So geht's:
test.py

Code: Alles auswählen

import subprocess

p = subprocess.Popen("python test2.py", stdin = subprocess.PIPE)
p.stdin.write("Fred vom Jupiter")
p.stdin.close()

print "ende"


test2.py

Code: Alles auswählen

import sys

print "OK1"
print "XXX%sXXX" % sys.stdin.readline()
print "OK2"


Allerdings ist das bei mir eine wackelige Geschichte... Wenn ich es in Scite Teste, dann muß bei test.py das print "ende" drin sein. Wenn ich das auskommentiere, geht es mal und dann wieder nicht...
Wenn ich es auf der Eingabeaufforderung teste, dann muß ich immer zum Schluß ein Enter drücken, damit der Interpreter beendet wird... Ich habe es auch mal versucht, vor dem p.stdin.close() ein p.stdin.write(os.linesep) einzufügen, damit readline() auf jeden Fall "weiter" macht. Das Ergebniss ist das selbe...

Und das bringt auch nichts:

test2.py

Code: Alles auswählen

import sys

print "OK"
while 1:
    line = sys.stdin.readline()
    if not line:
        break
    print line
print "OK2"

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Donnerstag 19. Januar 2006, 09:06

@ Jens: Danke dir, werds gleich mal checken.

@ Gerold: Kannst du mir noch sagen, wieso in
deinem Beispiel cPickle.dumps (mit's') verwendet wird ? Habe dazu auch bei Google nichts gefunden und in der Python Referenz, wie leider so oft, auch nichts.

Gruss, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Donnerstag 19. Januar 2006, 09:31

snakeseven hat geschrieben:@ Gerold: Kannst du mir noch sagen, wieso in
deinem Beispiel cPickle.dumps (mit's') verwendet wird ? Habe dazu auch bei Google nichts gefunden und in der Python Referenz, wie leider so oft, auch nichts.

Hi Seven!

Da ich davon gehört habe, dass unter Windows das Zielprogramm abgebrochen wird, wenn über sys.stdin des Zielprogramms der String "\x1a" geleitet wird, dachte ich mir, dass es besser sei, keine binären Daten über STDIN zu jagen. Da in der Erklärung von "cPicle.dumps" steht, dass damit ein String erzeugt wird, dachte ich mir, dass "dumps" sich schon darum kümmern wird, dass kein "EOF" (="\x1a") mitten im String auftauchen wird. Aber wahrscheinlich wird "dumps" exakt den gleichen Code erzeugen, wie ihn "dump" erzeugt.

Der einzige Unterschied wird also sein, dass ich vorher einen String erzeuge und diesen mit "write()" über die Leitung jage und in der Version von modelnine wird dieser Schritt ausgelassen, da "dump" sich schon darum kümmert, dass die Daten in das "File"-Objekt (in diesem Fall: STDIN des Kindprozesses) geschrieben wird.

http://python.org/doc/2.4.2/lib/node65.html

Das "BIN"-Problem besteht aber trotzdem noch, da ich ja beim "dumps" als Protokoll die Zahl 2 angegeben habe. Das war evt. nicht so gut. Hätte ich das nicht angegeben, dann würde mit Sicherheit ein "ASCII"-String generiert werden. Andererseits glaube ich nicht, dass mit "Pickle" etwas generiert wird, was den Datenfluss abbrechen könnte.

http://www.python-forum.de/viewtopic.php?p=29095#29095

lg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 19. Januar 2006, 10:12, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Donnerstag 19. Januar 2006, 09:35

gerold hat geschrieben:Da ich davon gehört habe, dass unter Windows das Zielprogramm abgebrochen wird, wenn über sys.stdin des Zielprogramms der String "\x1a" geleitet wird

Das könnte man allerdings ganz einfach umgehen, wenn man vor dem Senden ein string_escape macht!

Komischerweise, bleibt aber mein beschriebenes Problem bestehen, wenn man explizit als letztes ein "\x1a" sendet :)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Freitag 20. Januar 2006, 14:53

Die Diskussion über Vor- und Nachteile der Editoren habe ich in den Thread "Freie und komerzielle Editoren" reinverschoben, da der Thread sich selbstständig gemacht hat :wink:
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Freitag 20. Januar 2006, 15:31

Hi Gerold,
dein Sender-Empfänger Beispiel erzeugt in WingIDE folgende Exceptions:

[code=]WindowsError: (193, '%1 ist keine zul\xe4ssige Win32-Anwendung')

Rückverfolgung (innerste zuletzt):

Datei "C:\Ablage\Python\PythonScripte\sender.py", Zeile 1, in ?
#!/usr/bin/env python
Datei "C:\Ablage\Python\PythonScripte\sender.py", Zeile 54, in ?
main()
Datei "C:\Ablage\Python\PythonScripte\sender.py", Zeile 38, in main
cwd = os.curdir
Datei "C:\Programme\Python24\Lib\subprocess.py", Zeile 542, in __init__
errread, errwrite)
Datei "C:\Programme\Python24\Lib\subprocess.py", Zeile 706, in _execute_child
startupinfo)[/code]

Als nächstes werde ich es mal mit Active Python probieren. So als letzter Versuch sozusagen.

Gruss, Seven
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 20. Januar 2006, 16:16

snakeseven hat geschrieben:Als nächstes werde ich es mal mit Active Python probieren. So als letzter Versuch sozusagen.

Hi Seven!

Blöde Frage, aber stimmt bei dir der Pfad zu Python mit dem im Skript überein? Befindet sich "sender.py" im gleichen Ordner wie "empfaenger.py" und rufst du das Skript von dort aus auf? Funktioniert das Skript beim Aufruf von der Kommandozeile aus? Dieses Skript wurde mit WingIDE geschrieben. Es sollte also ziemlich sicher darin auch aufrufbar sein. :?

Code: Alles auswählen

    # Prozess aufrufen
    proc = subprocess.Popen(
        #Linux: ("/usr/bin/python", "empfaenger.py",),
        (r"C:\Python24\python.exe", "empfaenger.py"),
        stdin = subprocess.PIPE,
        stdout = subprocess.PIPE,
        cwd = os.curdir
    )

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
maguma :D

Beitragvon maguma :D » Freitag 20. Januar 2006, 16:32

hallo,

wenn ich mir recht erinnere müsste das unter windows auch so gehen!

Code: Alles auswählen

# Prozess aufrufen
    proc = subprocess.Popen(
        #Linux: ("/usr/bin/python", "empfaenger.py",),
        (r"/Python24/python.exe", "empfaenger.py"),
        stdin = subprocess.PIPE,
        stdout = subprocess.PIPE,
        cwd = os.curdir
    )


ist nur ein gedanke nichts weiteres.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 20. Januar 2006, 16:48

maguma :D hat geschrieben:wenn ich mir recht erinnere müsste das unter windows auch so gehen!

Code: Alles auswählen

        (r"/Python24/python.exe", "empfaenger.py"),

Hi!

Ja das könnte funktionieren, vorausgesetzt Python befindet sich auf dem gleichen Laufwerk wie das auszuführende Programm. Habe jetzt aber keine Lust, zu testen, ob nicht doch zumindest der Laufwerksbuchstabe angegeben werden muss. Das mit den Slash statt dem Backslash funktioniert sicher.

Aber wie ich gerade sehe, sucht Python "subprocess.py" im Ordner "C:\Programme\Python24\Lib". Dann dürfte Python bei Seven auch dort zu finden sein. Zumindest einen Ordner höher.

Code: Alles auswählen

Datei "C:\Programme\Python24\Lib\subprocess.py", Zeile 706, in _execute_child
  startupinfo)

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 20. Januar 2006, 17:17

Hi Seven!

Ich habe mein Beispiel verbessert. Jetzt funktioniert es, auch wenn dein Python ganz wo anders versteckt ist.

Code: Alles auswählen

    # Prozess aufrufen
    proc = subprocess.Popen(
        (sys.executable, "empfaenger.py"),
        stdin = subprocess.PIPE,
        stdout = subprocess.PIPE,
        cwd = os.curdir
    )

Man beachte "sys.executable".

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
snakeseven
User
Beiträge: 405
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon snakeseven » Freitag 20. Januar 2006, 18:55

Ja, VIELEN DANK !!
So funktionierts und so kann ich das jetzt in mein Script einbauen. Wieder ein Festplattenzugriff weniger :) Darf ich fragen, wie du auf "sys.executable" gekommen bist ? Nur so zum Nachlesen, um zu kapieren, was es macht.

Grüße, Seven
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Freitag 20. Januar 2006, 19:14

snakeseven hat geschrieben:Darf ich fragen, wie du auf "sys.executable" gekommen bist ? Nur so zum Nachlesen, um zu kapieren, was es macht.

Zum nachlesen gibts die Dokumentation des sys-Moduls :wink:

In der stdlib findet man doch immer wieder neue Sachen, auch wenn man Python schon lange nutzt, so ist das eben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Freitag 20. Januar 2006, 19:16

snakeseven hat geschrieben:Darf ich fragen, wie du auf "sys.executable" gekommen bist ? Nur so zum Nachlesen, um zu kapieren, was es macht.

Hi Seven!

Das war reine Intuition. Zuerst dachte ich mir, ich müsse die Registry auslesen um zum Pfad zu Python zu kommen. Dann überlegte ich mir, dass es ja auch genügen würde, wenn ich ein Modul imporiere, das immer im Python-Ordner liegt. Also probierte ich "import os; print os.__file__" aus. Dann hätte ich nur mehr den Pfad kürzen und je nach Betriebssystem "python" oder "python.exe" ran hängen müssen.

Während dieses Denkprozesses dachte ich mir aber, dass es doch sicher noch einen einfacheren Weg geben müsse. So bin ich auf "sys" gekommen. Mit "sys.path" komme ich an die Pfade, die von Python bei der Suche nach Modulen durchgesehen werden. Mit "sys.platform" kriege ich raus, ob das Python-Programm unter Windows oder einem anderen System läuft. Also dachte ich mir, dass "sys" der richtige Platz wäre, auch einen Hinweis auf die Executable von Python zu hinterlegen.

Mal schnell wieder "ipython" gestartet und sys importiert. Dann "sys." eingeben und die Tabulatortaste gedrückt. Schon kommt mir das Wort "executable" entgegen. Ein kurzes "sys.executable" zum Ausprobieren ob das den Pfad zur Python-Exe zurück gibt -- das wars.

Manchmal kommt man über zwanzig Ecken doch noch zum richtigen Ergebnis. :o

Zum schnellen Nachlesen nehme ich meist, wenn ich unter Windows arbeite, die CHM-Hilfe-Datei. Index --> Wort eingeben --> gefunden.

Brauche ich es nicht so ausführlich, oder will ich auch noch schnell etwas testen, starte ich "ipython" (mit Readlinesupport).

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], Holger Chapman