Daten aus Shell/Konsole kopieren

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.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo zusammen,

ich habe ein ein kleines Programm (Python), das einen "alias-Befehl" ausführt und dadurch einen Output in die Konsole/Shell schreibt. Nun möchte ich diesen Output in das kleine Python-Programm einlesen und damit weiterarbeiten. Wie kann man sowas machen?

MFG
lunar

@01detlef Was ist ein "alias"-Befehl?
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Also alias-Befehl ist sozusagen ein Shortcut. Man kann damit selber Namen für einen Befehl vergeben. Es wird also ein Programm dadurch ausgeführt.

Noch als Erklärung. Ich möchte ein Programm ausführen und den Output (der in der Konsole steht) einlesen.

detlef
BlackJack

@01detlef: Du suchst vielleicht das `subprocess`-Modul‽
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Ich bin gerade auf das gestoßen:

Code: Alles auswählen

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

import subprocess

# filename and searchterm
fn, term = 'access_log.gz', 'hello'
p = subprocess.Popen(['/usr/bin/zgrep', term, fn ], stdout=subprocess.PIPE)
for line in p.stdout:
    print line
Noch besser wäre nun, wenn ich nur nach einer Zeile im Output suche, so dass ich nur eine Zeile davon einlesen muss. Kann man dann irgendwie ein grep auf p.stdout machen oder wie kann sowas gehen?
BlackJack

@01detlef: Du musst alle Zeilen lesen, denn ohne die Zeile anzuschauen kann man ja schlecht entscheiden ob sie das enthält was Du suchst.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,
ich habe das nun mal probiert und ich bekomme immer den Fehler:

Code: Alles auswählen

p = subprocess.popen(command, stdout=subprocess.PIPE)
AttributeError: 'module' object has no attribute 'popen'
Was hat das zu bedeuten?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Dass du `Popen` falsch geschrieben hast.
lunar

@01detlef Ich weiß, was "alias" ist, ich habe Deinem Beitrag aber nicht entnehmen können, was Du damit anstellen willst.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Also ich habe auch Popen groß geschrieben und es kommt immer noch eine Fehlermeldung:

Code: Alles auswählen

  File "exe_save_cl.py", line 10, in <module>
    p = subprocess.Popen([command], stdout=subprocess.PIPE)
  File "/.../python/lib/python2.6/subprocess.py", line 595, in __init__
    errread, errwrite)
  File "/.../python/lib/python2.6/subprocess.py", line 1106, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
Woran liegt das?
lunar

@ 01detlef Dieser Fehler bedeutet, dass das Programm, welches Du versuchst auszuführen, nicht existiert. Wie sieht denn der Inhalt von "command" aus?
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

OKay,

es war natürlich ein Fehler im Befehl!!!!
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Man man, ich komme nicht so richtig weiter.
Der Befehl wird nun ausgegeben und es wird Text in die Konsole geschrieben.
Ich lasse mir den ausgeben und splitten mit

Code: Alles auswählen

for line in p.stdout:
    line =  line.rstrip('\n')
    line = string.split(line)
Nun fängt die eine Zeile mit 'CRW' an und dann folgt eine Zahl. Genau diese Zeile
möchte ich haben und deshalb wollte ich das so machen

Code: Alles auswählen

for line in p.stdout:
    line =  line.rstrip('\n')
    line = string.split(line)
    line = line[0]
    if (line[0] == 'CRW'):
       print line
usw.
Nun wird aber gemeckert, dass line[0] nicht geht. Dabei meine ich sowas schon mal gemacht zu haben...
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@01detlef:

Code: Alles auswählen

Traceback (most recent call last):
    Mecker: line[0] geht nicht
Wenn das Deine Fehlermeldung ist, kann Dir hier sicher keiner helfen. Eine exaktere Problembeschreibung wirkt Wunder ;)

zu Deinem Code:
Die Funktionen aus dem string-Modul sind veraltet, besser fährst Du mit der Methode des Stringobjektes.
Überleg mal, was `line = line[0]` macht und welche Konsequenzen das für folgende `line[0]`-Verweise hat, wenn das erste Element der split-Liste leer ist und ob Dein Test jemals wahr werden kann.
Vllt. hilft Dir die Stringmethode startswith weiter, für kompliziertere Pattern gibts das re-Modul.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

ich habe nun das re-Modul verwendet und es funktioniert so weit.

mfg
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Hm, ich hätte es ja so gelöst:

In der Shell:

Code: Alles auswählen

alias_befehl | skript.py
Im Skript:

Code: Alles auswählen

import sys

for line in sys.stdin:
    # tu was mit line
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

mein Problem war aber eher den Output in der Konsole durch die AUsführung eines Befehls herauszukopieren. Also es wird einiger Output erzeugt und davon möchte ich eine Zeile, die mit einem bestimmten Wort beginnt, einlesen. Ich habe da immer noch nicht wirklich eine Idee/Lösung und würde mich über einen Tipp freuen.

Code: Alles auswählen

for line in p.stdout:
    line =  line.rstrip('\n')
    #line = string.split(line)
    #line = line[0]
    #if (line[0] == 'CRW'):
     #  print line
So in der Art, nun soll nur noch die richtige Zeile eingelesen oder gesucht werden. GIbt es da eine bessere Lösung?
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Was ist mit den Tipps von jerch?
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

ok, aber einlesen muss ich jede Zeile erstmal mit der for-Schleife oder? Und dann kann ich re.split verwenden und sagen

Code: Alles auswählen

line = re.split(line)
if line[0] == '..':
   print line
   out = line[2]
Ist das sinnvoll? Also die gesuchte Zeile hat nach dem splitten drei Teile und ich möchte nur den dritten Teil in der Zeile haben.
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Nein, das ist nicht sinnvoll dafür das re-Modul zu bemühen. Strings haben automatisch eine .split()-Methode.
Wenn du weißt, dass Zeilen die mit dem Wort anfangen, immer eine bestimmte Anzhal von "gesplitteten Elementen" haben, dann reicht es das erste Element auf Gleichheit zu prüfen und anschließend mit den andren zu tun wofür du sie brauchst.
Antworten