Ausgabe aus Konsole holen

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.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Und zwar, will ich die Ausgabe vom Terminal in mein Python Programm bekommen, also mit Terminal Ausgabe (Benutze Linux) meine ich, z.B.: wenn ich einen subprocess gestartet habe, und der irgendwann irgendetwas zurück ins Terminal gibt, wie bekomme ich das dann in mein Python Programm? sprich in eine variable?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Via ``subprocess.Popen``. Suchfunktion verrät Details.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

ähm, mit dem subprocess öffne ich ja nur einen prozess, aber das war nicht gemeint. Ich meinte wie ich eine Ausgabe vom Terminal bekomme bzeiehungsweise halt Konsole
busfahrer
User
Beiträge: 111
Registriert: Donnerstag 9. Oktober 2008, 17:42

Hallo

@Leonidas hat dir das meiste doch schon verraten.

Guck doch mal hier http://pydoc.org/2.5.1/subprocess.html


Gruß...busfahrer
Alles wird gut ;-)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Um mal die Doku zu zitieren...
Replacing /bin/sh shell backquote
---------------------------------
output=`mycmd myarg`
==>
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Na mit dem stdout-Parameter von Popen.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Also bei mir kommt bei

Code: Alles auswählen

output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
syntax error
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Tja, Popen und PIPE gehören nun mal zum subprocess-Modul. Abhilfe schafft z.B.:

Code: Alles auswählen

from subprocess import Popen, PIPE
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Das erklärt aber nicht den angeblichen Syntax-Error! Da würde eher ein NameError geworfen ...

Ich kann das aber auch nicht nachvollziehen ... evtl. copy & paste Fehler?
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

So wollte ich das mal ausprobieren:

Code: Alles auswählen

#!/usr/bin/env python

import sys
import subprocess
process="firefox"
subprocess.Popen(process)
print
print
print
print
print
output=`mycmd myarg`
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0])
print output
print
print
print
print 
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

omg ... das sieht ja ***** aus.

Zunächst einmal kommt der Syntax-Fehler aus Zeile 12 - die hat ja mal nichts mit dem Hinweis zu tun, der Dir gegeben wurde! Probiere das doch einfach in einer Python-Shell aus - ohne sinnfreien Code drum herum.

Im Grunde brauchst Du ja nur snafus import Code und die Zeile 13. Natürlich musst Du "mycmd" gegen ein existierendes Kommando austauschen, gleiches gilt für "myargs". Probiere doch einfach mal "dir" aus (oder "ls" unter Linux).

EDIT: Zeile 13 sieht bei dir auch falsch aus! Schau Dir doch mal das exakte Posting davon oben an ...
Zuletzt geändert von Hyperion am Donnerstag 8. Januar 2009, 23:15, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Der Syntaxerror kommt von Zeile 12, Backticks sind nun mal so in Python nicht erlaubt. Das ist ja nicht Bash-Skript. Und ``Popen`` sollte man mit Listen und nicht mit Strings aufrufen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Weil ich so lieb bin :-)

Code: Alles auswählen

>>> from subprocess import Popen, PIPE
>>> Popen(["ls"], stdout=PIPE).communicate()[0]
'data\nlaby.py\nlaby.py~\n'
>>>
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

das heist unter myarg kann ich sowas wie "ls" bez. "dir" verstehen?
und was verstehe ich unter mycmd?

edit: vielen Dank Hyperion
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Lies doch mal einfach die Doku dazu durch! "myargs" ist doch nur ein Beispielstring, der Dir anzeigen sollte, dass man dort einen String angibt, der das Kommando enthält, welches durch Popen ausgeführt werden soll!

"myargs" steht dann für ein Argument, bei "ls" könnte man also so was wie "-l" angeben ...

Man kann natürlich beliebig viele angeben! Insgesamt wird Popen ja eine Liste übergeben, das erste Item der Liste ist eben das Kommando, danach kann man Parameter angeben.
Zuletzt geändert von Hyperion am Donnerstag 8. Januar 2009, 23:22, insgesamt 1-mal geändert.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Manchmal ist es wirklich hilfreich, wenn man ein wenig Tutorials durchmacht und Dokumentationen liest und ein wenig mitdenkt. Und "myarg" und "mycmd" stehen für "hier bitte etwas sinnvolles einsetzen".
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

See also: Where is the "Any Key"? :twisted:
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

gut, das habe ich jetzt mittlerweile mal verstanden, so, jetzt hab ich ein größeres vorhaben^^

jetzt gibt es z.b.: programme, wie nehmen wir mal ping
wenn ich z.b.: ping google mache, dann bekomm ich ja in abständen immer wieder eine neue ausgabe also eine neue reihe ensteht im terminal.

wie kann ich jetzt für jedes mal, das eine neue zeile kommt, diese zeile die gerade kam auslesen, und von mir aus das time=xx.x ms aus

64 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=11 ttl=247 time=54.8 ms
64 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=12 ttl=247 time=50.7 ms
64 bytes from fg-in-f104.google.com (72.14.221.104): icmp_seq=13 ttl=247 time=45.1 ms
........
....

anzeigen lassen? und das bei jeder zeile neu auslesen die neu kommt?

ist das in diesem ausmaß überhaupt machbar?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Folgender Code fiele mir so auf die Schnelle ein:

Code: Alles auswählen

#! /usr/bin/python
# -*- coding: utf-8 -*-

from subprocess import Popen, PIPE
from time import time, sleep

def main():
    print "Starte ...\n"
    p = Popen(["ping", "www.google.de", "-w 3", "-i 2"], stdout=PIPE)
    while p.poll() is None:
        #print p.stdout.read(1),
        print "läuft noch", time()
        sleep(1)
    print "\nEnde"
    print "Ausgabe:"
    print p.stdout.read()

if __name__ == "__main__":
    main()
Allerdings kommt man so auch nicht permanent an die Ausgabe. Man kann zwar in der Schleife per p.stdout.read(100) ständig 100 Bytes aus dem "Stream" holen, aber dann muss man sich zumindest noch überlegen, wie man feststellt, dass eine "Zeile" der Ausgabe fertig ist. (die 100 ist nur ein Beispiel!)

So richtig "schön" wirds vermutlich nur durch die Benutzung von Threads. Einer startet den Prozess wie hier, ein anderer liest die Ausgabe permanent aus und verarbeitet sie weiter.

Zudem steht zu überlegen, wie man den Prozess zur Not killt!

Exception Handling fehlt da natürlich auch noch ...

EDIT: Zur Verarbeitung der Ausgabe bzw. dem Auswerten bestimmter Daten schau Dir mal Regular Expressions an! (Gibt nen gutes Howto in der Doku!)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Man sollte alle Parameter in eigene Elemente in der Liste schreiben, denn ``ping`` kennt kein ``-w 3`` Parameter sondern nur ``-w`` gefolgt von ``3``. Da gibt es keine High-Level zuordnung von Parameter zu wert, das erledigen dann Paring Libraries wie Getargs, POPT etc.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten