Seite 1 von 2

Ausgabe aus Konsole holen

Verfasst: Donnerstag 8. Januar 2009, 22:07
von gugugs
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?

Verfasst: Donnerstag 8. Januar 2009, 22:14
von Leonidas
Via ``subprocess.Popen``. Suchfunktion verrät Details.

Verfasst: Donnerstag 8. Januar 2009, 22:39
von gugugs
ä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

Verfasst: Donnerstag 8. Januar 2009, 22:44
von busfahrer
Hallo

@Leonidas hat dir das meiste doch schon verraten.

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


Gruß...busfahrer

Verfasst: Donnerstag 8. Januar 2009, 22:46
von snafu
Um mal die Doku zu zitieren...
Replacing /bin/sh shell backquote
---------------------------------
output=`mycmd myarg`
==>
output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]

Verfasst: Donnerstag 8. Januar 2009, 22:47
von EyDu
Na mit dem stdout-Parameter von Popen.

Verfasst: Donnerstag 8. Januar 2009, 22:59
von gugugs
Also bei mir kommt bei

Code: Alles auswählen

output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
syntax error

Verfasst: Donnerstag 8. Januar 2009, 23:01
von snafu
Tja, Popen und PIPE gehören nun mal zum subprocess-Modul. Abhilfe schafft z.B.:

Code: Alles auswählen

from subprocess import Popen, PIPE

Verfasst: Donnerstag 8. Januar 2009, 23:04
von Hyperion
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?

Verfasst: Donnerstag 8. Januar 2009, 23:09
von gugugs
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 

Verfasst: Donnerstag 8. Januar 2009, 23:13
von Hyperion
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 ...

Verfasst: Donnerstag 8. Januar 2009, 23:15
von Leonidas
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.

Verfasst: Donnerstag 8. Januar 2009, 23:17
von Hyperion
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'
>>>

Verfasst: Donnerstag 8. Januar 2009, 23:18
von gugugs
das heist unter myarg kann ich sowas wie "ls" bez. "dir" verstehen?
und was verstehe ich unter mycmd?

edit: vielen Dank Hyperion

Verfasst: Donnerstag 8. Januar 2009, 23:21
von Hyperion
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.

Verfasst: Donnerstag 8. Januar 2009, 23:21
von Trundle
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".

Verfasst: Donnerstag 8. Januar 2009, 23:56
von Leonidas
See also: Where is the "Any Key"? :twisted:

Verfasst: Donnerstag 8. Januar 2009, 23:59
von gugugs
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?

Verfasst: Freitag 9. Januar 2009, 00:36
von Hyperion
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!)

Verfasst: Freitag 9. Januar 2009, 00:41
von Leonidas
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.