Linux Stdout in Array einlesen und ausgeben

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.
Antworten
falke
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2016, 12:10

Hallo zusammen,

ich taste mich gerade etwas an Python an und möchte auf Linux-Ebene Stdout mit ls -al die Zeilen einlesen und das Element anzeigen lassen wo die Filegröße angezeigt wird.Unten ist das Skript aufgeführt. Wieso bekomme ich den Fehler IndexError: list index out of range obwohl len(list) 9 anzeigt?
Ausgabe ls -la:

rwxr-xr-x 1 maxmuster users 356 27. Mai 2015 Zufallsgenerator.py

Code: Alles auswählen

import os
import subprocess

cmdstring = "ls -al"
p = subprocess.Popen(['ls','-al'], stdout=subprocess.PIPE)
list = ()
i = ()
for i in p.stdout.readlines():
    i = i.split(" ")
    list = filter(str.strip, i)          # Loesche alle leeren Elemente ''
    print i
    print filter(str.strip, i)
    print list
    print "lange list=" , len(list)
    print list[0],list[1]          # Wenn ich hier list[2] und weiter eintrage gibt es einen Fehler
Zuletzt geändert von Anonymous am Freitag 28. April 2017, 13:46, insgesamt 2-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Hallo,



bei mir geht es.
Zeige mal den gesamten Output + Fehlermeldung.
Wichtig ist eigentlich was in 'list' steht kurz vor der Fehlermeldung.
Übrigens ist list als Variablenname sehr unschön.
falke
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2016, 12:10

Hallo,

der Code funktioniert nicht wenn man in der letzten Zeile noch weitere Elemente hinzufügt print list[0],list[1],list[2] ...
dann kommt der Fehler.

./listDirectory.py
['insgesamt', '20508\n']
['insgesamt', '20508\n']
['insgesamt', '20508\n']
lange list= 2
insgesamt 20508
Traceback (most recent call last):
File "./listDirectory.py", line 18, in <module>
print list[0],list[1],list[2]
IndexError: list index out of range
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Hallo,


das habe ich mir gedacht.
Schaue dir mal die Fehlermeldung genauer an.
Kurz vor der Fehlermeldung steht nämlich, dass die Länge deiner 'list' nur noch 2 Eintäge beinhaltet.
Da kannst du schlecht mit list[2] auf das dritte Element deiner 'list' zugreifen.

Problem ist, dass ls -al nicht nur die Attribute der Files / Directorys anzeigt sondern eben auch die genutzten Blöcke dafür -> "Insgesamt 20508"
falke
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2016, 12:10

Hallo sebastian,

wenn du aber aus der letzten Zeile print list[0],list[1] , list[2] löschst dann ist die Liste plötzlich 9 Elemente lang. Das ist was mich wundert.

Ausgabe ohne Fehler list[2] in der letzten Zeile:



lange list= 9
-rw-r--r-- 1
['-rwxr-xr-x', '1', 'maxmuster', 'users', '', '', '', '', '', '356', '27.', 'Mai', '2015', '', 'Zufallsgenerator.py\n']
['-rwxr-xr-x', '1', 'maxmuster', 'users', '356', '27.', 'Mai', '2015', 'Zufallsgenerator.py\n']
['-rwxr-xr-x', '1', 'maxmuster', 'users', '356', '27.', 'Mai', '2015', 'Zufallsgenerator.py\n']
Zuletzt geändert von falke am Freitag 28. April 2017, 09:17, insgesamt 1-mal geändert.
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Hallo,



dann kommt ja auch kein Fehler mehr und deine for-Schleife wird weiterhin abgearbeitet.
falke
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2016, 12:10

Hallo,

wie kann ich mit dann von jede Zeile das 4.Element anzeigen lassen?.
Nachdem abarbeiten der letzten Zeile funktioniert es doch auch :-(

Code: Alles auswählen

for i in p.stdout.readlines():
    i = i.split(" ")
    list = filter(str.strip, i)          # Loesche alle leeren Elemente ''
    print i
    print list
    print "laenge list=" , len(list)
print list[4]
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Du könntest beispielsweise dein 'ls -al' anpassen zu soetwas 'ls -al | egrep "^-" '
Oder du prüfst ob deine 'list' wirklich immer 9 Elemente besitzt.

Code: Alles auswählen

...
... # PSEUDOCODE
for ... : 
    if len(list) == 9:
        print list[4]

falke
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2016, 12:10

Hallo Sebastian,

das war es tatsächlich. Wenn das letzte Element (Datei Name) ein Leerzeichen hatte war die Zeile nicht mehr 9 Elemente lang sondern 10.
Ich bin davon ausgegangen, dass es immmer 9 Elemente sein müssen.

Ich danke dir für deine Unterstüzung.

Viele Grüße
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@falke: zu Deinem Code: cmdstring, list und i werden Werte zugewiesen, die nicht benutzt werden. Man muß keine Variablen in irgendeiner Form definieren, man benutzt sie einfach, wenn man sie braucht. »split(" ")« splittet bei jedem Leerzeichen, also entstehen leere Elemente, wenn mehrere Leerzeichen hintereinanderstehen, wie z.B. bei "ls" um eine schöne Spaltenformatierung zu bekommen. Das ist sicher nicht das, was Du willst.

Exterene Programme für Dinge zu benutzen, die man auch einfach mit Python-Funktionen erledigen kann, ist schlechter Stil. Zumal hier durch Benutzung von »ls« das Programm auf Un*x beschränkt wird, deutlich komplizierter und fehleranfälliger ist, als die direkte Lösung:

Code: Alles auswählen

import os

for filename in os.listdir("."):
    stat = os.stat(filename)
    print(filename, stat.st_size)
BlackJack

Oder mit `os.path.getsize()`:

Code: Alles auswählen

import os
 
for filename in os.listdir(os.curdir):
    print(filename, os.path.getsize(filename))
Antworten