Systeminfos mit sys.argv auslesen

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.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Hallo Zusammen
Erstmal ich bin neu hier und verstehe nicht all zu viel von Python und weiß auch nicht in Welche Abteilung diese Frage gehört.
Ich muss für die Schule ein Python Script schreiben, das die Folgenden CPU und Memory Infos ausgibt:
-CPU:
  • - Vendor
  • - Model
  • - mhZ
  • - Cache
-Memory:
  • - Memory Total
  • - Memory Free
  • - Buffers
  • - Cached
Das habe ich ohne Probleme hinbekommen. Die Infos werden am Anfang des Scripts als Modul von einem anderen Script importiert. Nun zieht sich die Aufgabe weiter und man soll nun mit sys.argv Parameter hinter der Eingabe aufrufen, welche dann mit den zugehörigen Infos erscheinen.

Mein Code sieht momentan so aus:

Code: Alles auswählen

#!/usr/bin/python3.2
# Skript: M122_Scripts/python/systeminfo.py

import sys
import listcpuinfo
import listmemoryinfo

mem = listmemoryinfo.getmemoryinfo()

memtotal = mem[0]
memfree = mem[1]
buffers = mem [2]
cached = mem[3]

for sys.argv in mem:
  print(str(listmemoryinfo in sys.argv))
    
cpu = listcpuinfo.getcpuinfo()

vendor = cpu[1]
model = cpu[4]
mhz = cpu[6]
cache = cpu[7]


for sys argv in cpu:
  print(int(sys.argv in cpu))
Der Code funktioniert irgendwie gar nicht und ich habe kein Plan wieso.
Ich hoffe ihr könnt mir bei meinem Problem weiterhelfen.

MFG :D

MrAeon
mcdwerner
User
Beiträge: 113
Registriert: Donnerstag 7. Juli 2011, 14:27

hier steht, was Du mir sys.argv auslesen kannst:
http://docs.python.org/2/library/sys.html

Erklär auch mal die Fragestellung in Deinen Worten, mir scheint da ein Missverständnis vorzuliegen.
Benutzeravatar
kbr
User
Beiträge: 1510
Registriert: Mittwoch 15. Oktober 2008, 09:27

So wie Du es beschreibst, hast Du die Aufgabe falsch verstanden. Mit sys.argv hast Du Zugriff auf die Parameter, die einem Script per Kommandozeile übergeben werden. Dies kannst Du auch in der Python-Doku nachlesen. Vermutlich sollst Du etwas in der Form

Code: Alles auswählen

$ python deinscript.py cpu
umsetzen und dann nur die Info zur CPU ausgeben.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Ja tut mir leid. Ich habe vergessen den Letzten Satz zu schreiben.

Ich sollte am Schluss mit

Code: Alles auswählen

>> ./systeminfo.py vendor model mhz cache totalmemory freememory buffers cached
die Angaben herauslesen können, damit ich am Schluss ca diese ausgabe habe:

CPU
Vendor: Intel blablabal
Model: i7 3.2ghZ
mhz: ...
etc.

Ist damit die Sache ein bisschen klarer geworden?
mcdwerner
User
Beiträge: 113
Registriert: Donnerstag 7. Juli 2011, 14:27

was mir noch nicht klar ist: wo genau hängst Du fest?
Hast Du Dir die von mir verlinkte Doku zu sys.argv durchgelesen und weisst Du was sys.argv macht/ist?
Edit:
als erstes lohnt es sich diese Schleife anzuschauen, um Dir klar zu machen was Du meinst, dass sie macht und um zu testen, was sie tatsächlich macht:

Code: Alles auswählen

for sys.argv in mem:
  print(str(listmemoryinfo in sys.argv))
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Ja so wie ich das herausgefunden habe und es uns unser Lehrer erklärt hat, nimmt sys.argv die Parameter die man hinter der auszuführenden Python Datei angibt,
und verwendet diese dann, sobald als man sie aufruft.

Ich will ja nun die Parameter die ich hintendran eben eingegeben habe (vendor model, etc...) in der listmemoryinfo. Datei suchen und die Felder 0-3 ausgeben mit den entsprechenden namen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

MrAeon hat geschrieben: Ich will ja nun die Parameter die ich hintendran eben eingegeben habe (vendor model, etc...) in der listmemoryinfo. Datei suchen und die Felder 0-3 ausgeben mit den entsprechenden namen.
Wie *genau* sieht denn die Datei aus? Ist die Datei und das Format der Daten darin vorgegeben oder frei wählbar?

Im Grunde genommen ist das Übergeben des Dateinamens bzw. das Auslesen selbigens aus ``sys.argv`` ein Kinderspiel - das Parsen der Datei und der darin befindelichen Infos dürfte vermutlich spannender sein ;-)

Für komplexeres Kommandozeilen-Parsing gibt es ürbigens das ``argparse``-Modul. Damit kannst Du auch Schalter, Optionen einfach definieren und bekommst einen automatischen Hilfetext generiert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Also in der Frage habe ich ja den Code von meiner Datei rein geschrieben.

in der 4-6 zeile importiere ich ja die Datei-Module.

Code: Alles auswählen

import sys
import listcpuinfo
import listmemoryinfo
Die Dateien listcpuinfo und listmemoryinfo sind beide gleich aufgebaut:

Code: Alles auswählen

#!/usr/bin/python3.2
# Skript: M122_Scripts/python/listmemoryinfo.py
def getmemoryinfo():
  memoryinfo = open('/proc/meminfo', 'r')
  liste = memoryinfo.readlines()
  return liste

In diesen Beiden Dateien hole ich ja die Infos des Prozessors und des Arbeitsspeicher heraus.

Und eben diese Infos will ich nach her mit sys.argv herausgeben.
BlackJack

@MrAeon: Dazu müsstest Du die Informationen derart in einer Datenstruktur speichern, dass man über eine gegebene Zeichenkette, den dazugehörigen Wert bekommen kann. Hier würde sich offensichtlich ein Wörterbuch, als der Datentyp `dict` für eignen.

Wobei ich mich Frage ob die Funktionen in den Modulen nicht vielleicht doch etwas mehr mit den Dateien aus ``/proc/`` anstellen sollten, denn zumindest für die CPU-Informationen stimmen die Indizes beim Zugriff in Deinem Beispiel nicht, beziehungsweise wenn dann ist das ein Sonderfall der bei *Deinem* Rechner vielleicht stimmt, aber sicher nicht allgemein.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Also der Rechner ist Linux, ich weiß nicht ob ich das noch hätte erwähnen sollen.
wen ich den befehl

Code: Alles auswählen

for sys.argv in mem:
  print(str(listmemoryinfo in sys.argv))
nicht ausführe, dafür aber das Script hier:

Code: Alles auswählen

import listcpuinfo

cpu = listcpuinfo.getcpuinfo()

vendor = cpu[1]
model = cpu[4]
mhz = cpu[6]
cache = cpu[7]

print('++++++++++++++++++++++++')
print('Basic CPU information:')
print('++++++++++++++++++++++++')
print(vendor+model+mhz+cache)
erhalte ich die gewünschte Ausgabe:
Bild

Nun wil ich eigentlich nur den 2ten print Befehl ändern, wobei ich nachher selber die Parameter bestimmen kann welche es von den 4en ausgebn soll
BlackJack

@MrAeon: Das mag ja sein, aber nicht bei jedem Rechnermodell müssen die Informationen an genau diesen Indizes in der Liste stehen. Solange Du das nicht irgendwo dokumentiert findest, dass das garantiert ist, kann man sich da nicht drauf verlassen.

Edit: So eine Ausgabe kann zum Beispiel auch so aussehen:

Code: Alles auswählen

$ cat /proc/cpuinfo 
Processor       : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS        : 795.44
Features        : swp half thumb fastmult vfp edsp java tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xb76
CPU revision    : 7

Hardware        : BCM2708
Revision        : 000f
Serial          : 00000000093365cf
Edit2: Bei Dir werden ja sogar falsche Ergebnisse ausgegeben. Vergleich mal die Namen in Deinem Skript und welche Informationen da tatsächlich für ausgegeben werden!
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Wie gesagt, unser Lehrer hatte diesen Pfad auf den Arbeitsblättern und beim Script ohne sys.argv funktioniert es auch...
als ich vermute ich habe beim sys.argv Befehl den Fehler...

ja eben, ich beziehe die Informationen auch aus dieser Datei.
Wen es mich nicht täuscht auch aus der gleichen Datei.
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@MrAeon: wenn das stimmt was Du hier im Screenshot hast, dann enthält »mhz« den String "microcode : 0x17\n" und »cache« den String "cpu MHZ : 3392.389\n".
Ich würde nochmals Deine Namensgebung überprüfen. Und wie BlackJack schon gesagt hat, die Zeilen enthalten ja schon einen Hinweis, was in der Zeile steht, also ist es das einfachste diese in ein dict zu packen.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

@Sirius3

Die Namensgebung ist nicht das Problem. Ich habe dort nur die Zahlen für die Fields nicht richtig angegeben.

Das Hauptproblem das ich habe ist eben, das ich mit sys.argv die Parameter die ich eingebe aufrufen will, sprich, den vendor, model, etc aufrufen will, hinter denen dann cpu[1](und so) steht.

Verstehst du was ich damit sagen will?

Vielen Dank übrigens das ihr versucht mir zu Helfen ;)
BlackJack

@MrAeon: Doch die Namensgebung *ist* das Problem. Du kannst keine festen Zahlen nehmen, weil der Inhalt der Datei extrem vom Prozessor abhängt. Es macht keinen Sinn feste Zahlen zu nehmen, sondern man muss die Daten in den Zeilen auswerten. Also die Zeilen in Schlüssel/Wert-Paare aufteilen und in einer geeigneten Datenstruktur speichern. Zum Beispiel in einem Wörterbuch (Python-Datentyp `dict`). Schau Dir einfach noch mal meinen Beitrag von weiter oben an, wo die ``/proc/cpuinfo`` auf einem ARM-System steht. Da kommst Du mit Deinen festen Zahlen nicht weiter. Hier noch ein anderes Beispiel, für den Fall, dass Dir ein ARM-SOC zu exotisch vorkommt:

Code: Alles auswählen

$ cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 16
model           : 5
model name      : AMD Athlon(tm) II X4 620 Processor
stepping        : 2
cpu MHz         : 2599.960
cache size      : 512 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt npt lbrv svm_lock nrip_save
bogomips        : 5199.91
TLB size        : 1024 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate
...
Hier ist zum Beispiel die ``microcode``-Zeile nicht vorhanden, die bei Dir mit in der Ausgabe steht. Mit festen Indizes kann man einfach nicht arbeiten.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

@BlackJack

Wie würdest du es dann machen?
Benutzeravatar
kbr
User
Beiträge: 1510
Registriert: Mittwoch 15. Oktober 2008, 09:27

@MrAeon: BlackJack hat doch schon beschrieben, wie er es machen würde. Allerdings hat er Dir nicht die Implementierung geliefert — schließlich ist es ja Deine Hausaufgabe. Und er tut Dir damit auch einen Gefallen, denn nur wenn Du es selbst umsetzt, hast Du anschließend auch was gelernt — sowohl über die Implementierung als auch zur Recherche der Lösung.

Was Du bisher hast ist ein Skript, welches Informationen über das System liefert (zwar nicht robust, aber immerhin für Deine Plattform).

Was Du nun brauchst ist beispielsweise eine Funktion, die aus diesen Informationen einen bestimmten Wert zurück liefert:

Code: Alles auswählen

def get_info('cpu'):
    # gibt gewünschte Information zurück
Mit 'sys.argv' hast Du Zugriff auf die Kommandozeilenparameter (oder etwas aufwendiger aber dafür professioneller mit 'argparse'). Nun brauchst Du Dein Skript nur noch so zu erweitern, dass die gewünschte Information (oder auch mehrere) ausgegeben wird.

Das wäre jedenfalls ein möglicher Lösungsansatz, den ich Dir zur Übung vorschlagen würde.
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Das ist doch sowas in der Art, oder?
MrAeon hat geschrieben:

Code: Alles auswählen

#!/usr/bin/python3.2
# Skript: M122_Scripts/python/listmemoryinfo.py
def getmemoryinfo():
  memoryinfo = open('/proc/meminfo', 'r')
  liste = memoryinfo.readlines()
  return liste
Ich hatte auch schon bereits ein Script geschrieben, welches die Kommandozeilenparameter wieder ausgibt, was ja aber nicht der sinn der Sache ist.
Kann ich eigentlich die Abfrage und "Ausgabe" von sys.argv in einem Print machen oder wäre es schlauer noch ein bis zwei weiter Code-Zeilen zu schreiben?
Benutzeravatar
MrAeon
User
Beiträge: 13
Registriert: Montag 27. Mai 2013, 14:25

Ich bin schon ein bischen weiter gekommen:

Bild

nur sollte eben stat den lauter 1en die besagten infos vom CPU kommen...
Ich bin immer noch der meinung das mit dem print noch etwas nicht Stimmt und nicht mit dem herausgesuchten Informationen...
Wie schon einmal erwähnt ist dieser Code schon fast über meinem Wissensstand von Python, da ich bis jetzt erst ca 14h Python in der Schule habe.
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo MrAeon,
Du solltest dringend mal ein »print(sys.argv)« vor und eines nach Deiner for-Schleife einfügen und Dich dann fragen, was Du mit »sys.argv« gerade angestellt hast.

Code: Alles auswählen

>>> cpu = ["processor       : 0", "cpu family      : 1", "model           : 5"]
>>> for info in cpu:
...     print(info, info in cpu)
... 
processor       : 0 True
cpu family      : 1 True
model           : 5 True
>>> 
Antworten