ubuntuusers.de

Python: subprocess.Popen mit PIPE auslesen...Fehler in subprocess.py

Status: Gelöst | Ubuntu-Version: Ubuntu 9.10 (Karmic Koala)
Antworten |

debobs

Avatar von debobs

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 248

Hallo,

ich bin gerade dabei eine Hamachi-GUI zu schreiben. Soweit ist alles gut, bis ich versucht habe anstatt dem Modul "os" das Modul "subprocess" zu nehmen. Ich versuche nämlich wegen der Auflistung von Netzwerken und Mitgliedern den Befehl "hamachi list" auszulesen. Jedoch kommt der Fehler (der meines Erachtens nichts mit mir zu tun hat):

Traceback (most recent call last):
  File "machy.py", line 18, in <module>
    liste = subprocess.Popen(["hamchi", "list"], stdout="subprocess.PIPE")
  File "/usr/lib/python2.6/subprocess.py", line 588, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/usr/lib/python2.6/subprocess.py", line 945, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: 'str' object has no attribute 'fileno'

Die entsprechende Stelle im Quelltext:

1
2
3
4
liste = subprocess.Popen(["hamchi", "list"], stdout="subprocess.PIPE")
liste.wait()
subprocess.stdout.read()
list = liste

Ich hoffe mir kann jemand helfen!

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Doch, der Fehler liegt bei dir. Dieser Teil ist falsch:

stdout="subprocess.PIPE"

Die Quotes müssen weg. Richtig ist also:

stdout=subprocess.PIPE

Außerdem nicht subprocess.stdout, sondern liste.stdout, zumal der Name schlecht gewählt ist. Besser wäre etwas wie prozess oder der Name des aufzurufenden Programms. Und wenn du die Rückgabe von read() an keinen Namen bindest, bringt es dir auch nicht allzu viel. 😉 Und die letzte Zeile ist relativ sinnlos.

Ich will nicht unken, aber ich glaube bis zur vernünftig programmierten GUI dauert es noch ein bißchen bei dir...

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

1
liste = subprocess.Popen(["hamchi", "list"], stdout=subprocess.PIPE)

Der Name liste ist wenig sinnvoll. Das built-in list zu überschreiben ist noch weniger empfehlenswert...

debobs

(Themenstarter)
Avatar von debobs

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 248

Danke für die Antworten, aber gebracht hat es leider wenig. Nachdem ich den Code geändert habe (u.a. die Variablennamen), kommt ein anderer Fehler:

  File "machy.py", line 18, in <module>
    netzwerke = subprocess.Popen(["hamchi", "list"], stdout=subprocess.PIPE)
  File "/usr/lib/python2.6/subprocess.py", line 595, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1092, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Code:

1
2
3
4
netzwerke = subprocess.Popen(["hamchi", "list"], stdout=subprocess.PIPE)
netzwerke.wait()
netzwerke.stdout.read()
netzwerkliste = netzwerke

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Vielleicht wird Hamachi ja mit hamachi und nicht mit hamchi aufgerufen. ☺

Die anderen Fehler hast du übrigens immer noch nicht korrigiert.

debobs

(Themenstarter)
Avatar von debobs

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 248

snafu1 schrieb:

Vielleicht wird Hamachi ja mit hamachi und nicht mit hamchi aufgerufen. ☺

Ups 😀 Jetzt geht das starten. Allerdings wird es immer noch nicht richtig angezeigt. Statt der Netzwerk- und Benutzerliste kommt nun "<subprocess.Popen object at ****>"(**** ändert sich. Ist jedoch immer "0xzahlenbuchstaben"). Hängt dies mit der Darstellung von Tkinter zusammen?

Jetziger Code für die Liste:

1
2
3
4
netzwerke = subprocess.Popen(["hamachi", "list"], stdout=subprocess.PIPE)
netzwerke.wait()
netzwerke.stdout.read()
netzwerkliste = netzwerke

Code für die Darstellung der Liste:

1
netzwerkliste = Tkinter.Label(root,text=netzwerkliste)

PS: Was für andere Fehler? Ich habe den Variablennamen geändert und "subprocess.stdout" durch "variable.stdout" geändert. War da sonst noch was das ich übersehen habe?

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Wieso nutzt Du nicht das Python-Flag beim Code posten? Das liest sich schöner und man hat Zeilennummern ...

Beschreib doch mal, was sich in zeile 3 und in Zeile 4 tut! Lies Dir dazu noch mal die Doku zu subprocess durch (Zeile 3). Für Zeile 4 bedarf es nur elementarer Python-Kenntnisse.

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Lies doch einfach mal die Doku. Da ist auch ein schönes Tutorial, um erstmal Grundkenntnisse in Sachen Python zu erlangen.

Zusammenkopieren von Code (was ich hier mal unterstelle) wird dich nicht weiter bringen. Du merkst es ja gerade selbst.

debobs

(Themenstarter)
Avatar von debobs

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 248

- Python-Flags nachträglich gesetzt

- Zeile 3 liest mit read() das Ergebnis von Zeile 1 aus wo es mit stdout aufgeschrieben wurde (oder so ähnlich)

- Zeile 4 speichert das Resultat von Zeile 1-3 in der Variable netzwerkliste

- habe die Zeilen 1-3 kopiert, habe mir aber den Artikel dazu durchgelesen

- habe A byte of Python ungefähr bis zur Hälfte durchgelesen, hatte dann einfach keine lust mehr.

PS: Ich habe vorher auch selbst nach einer Lösung gesucht, aber keine gefunden.

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

debobs schrieb:

- Zeile 3 liest mit read() das Ergebnis von Zeile 1 aus wo es mit stdout aufgeschrieben wurde (oder so ähnlich)

Und jetzt überleg mal, was mit dem Ergebnis passiert ...

- Zeile 4 speichert das Resultat von Zeile 1-3 in der Variable netzwerkliste

Zeilen haben kein Resultat. Wenn du ABOP wirklich zur Hälfte durchgelesen hast, musst du wissen, was Zeile vier wirklich bewirkt, und warum sie im Bezug auf dein Problem unsinnig ist.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

debobs schrieb:

- Python-Flags nachträglich gesetzt

- Zeile 3 liest mit read() das Ergebnis von Zeile 1 aus wo es mit stdout aufgeschrieben wurde (oder so ähnlich)

Was glaubst Du ist denn das Ergebnis von read()? Was gibt read() zurück? Oder gibt es None zurück?

- Zeile 4 speichert das Resultat von Zeile 1-3 in der Variable netzwerkliste

Nein. In Zeile 4 bindest Du den Inhalt von netzwerke an einen neuen Namen. Vermutlich also sinnlos, denn ob Du nun mittels netzwerke.irgend_was auf das Popen-Objekt zugreifst, oder per netzwerkliste.irgend_was 😉

debobs

(Themenstarter)
Avatar von debobs

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 248

Lunar schrieb:

Und jetzt überleg mal, was mit dem Ergebnis passiert ...

Versteh ich nicht ganz...

Zeilen haben kein Resultat. Wenn du ABOP wirklich zur Hälfte durchgelesen hast, musst du wissen, was Zeile vier wirklich bewirkt, und warum sie im Bezug auf dein Problem unsinnig ist.

Mit dem "Resultat" meinte ich das was in den Zeilen 1-3 mit der Variable netzwerk angestellt wurde. Zuerst wurde der Befehl "hamachi list" ausgeführt und in Zeile 2 wird anschließend gewartet bis der Befehl fertig ist um ihn danach in Zeile 3 auszulesen. Du hast eigentlich recht, Zeile 4 ist unsinnig. Aber ich schrieb sie dazu weil es mir logisch erschien. Wenn sie da ist kann man sie immer noch ignorieren. Außerdem es könnte doch sein dass ich in Zeile 4 etwas falsch gemacht habe ☺

Wie dem auch sein, mein eigentliches Problem, dass mir die Ausgabe nicht/fehlerhaft angezeigt wird, wird dadurch auch nicht gelöst!

Lysander schrieb:

debobs schrieb:

- Python-Flags nachträglich gesetzt

- Zeile 3 liest mit read() das Ergebnis von Zeile 1 aus wo es mit stdout aufgeschrieben wurde (oder so ähnlich)

Was glaubst Du ist denn das Ergebnis von read()? Was gibt read() zurück? Oder gibt es None zurück?

Im Idealfall sollte netzwerke.stdout.read() folgendes zurückliefern:

 * [afdion]
       5.132.95.201  

Was es aber zurückliefert ist hier beschrieben.

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

Doch, dein Problem wird gelöst, wenn du die Tipps anwendest.

Gib doch die Befehle mal nacheinander im Interpreter ein und beobachte, was in Zeile 3 passiert.

debobs

(Themenstarter)
Avatar von debobs

Anmeldungsdatum:
30. Oktober 2008

Beiträge: 248

Ich danke euch, habs gefunden. Wenn ich

1
netzwerkliste = subprocess.Popen(["hamachi", "list"], stdout=subprocess.PIPE)

eingeben kommt des ding mit "...object at 0x..." und wenn ich es mit read() auslese kommt das eigentliche ergebniss. Also muss man nur den read() teil einer Variable zuweisen. Falls es jemand braucht:

1
2
3
netzwerkliste = subprocess.Popen(["hamachi", "list"], stdout=subprocess.PIPE)
netzwerkliste.wait()
netzwerkliste = netzwerkliste.stdout.read()

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2133

Wohnort: Gelsenkirchen

"Einer Variable zuweisen" war mit "an einen Namen binden" gemeint. 😉 In Python gibt es eigentlich keine Variablen.

Antworten |