Externes Kommando mit Parametern ausführen

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

Hallo zusammen,

ich möchte mit Python ein Script schreiben, dass einen Linux-Befehl ausführt. Ich habe schon gesucht und auch einige Sachen gefunden, aber mein Problem ist, dass der Linux-Befehl zwei Parameter hat und benötigt.

Also der Befehl in der Konsole ist /..../../Deform <Para1> <Para2>

Wie kann ich das in einem Python-Script machen? Ich habe was über import os gelesen, aber das bekomme ich irgendwie nicht hin:

Code: Alles auswählen

import os
a = os.popen('/.../Deform')
Ich weiss nicht wie das mit den Parametern funktionieren soll?

detlef
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Code: Alles auswählen

import subprocess
subprocess.call([command, arg1, arg2])
Wobei natürlich je nach Anwendungszweck andere Varianten aus dem subprocess-Modul sinnvoller wären.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Ok,

vielen Dank, das hilft mir weiter. Kann man nun sagen, dass die arg1 bzw. arg2, die ebenfalls Dateien sein sollen, in einem anderen Verzeichnis liegen:

Code: Alles auswählen

arg1 = "/.../..../bla"
Und noch eine Frage, ich öffne eine Datei und ersetze etwas, aber wie kann ich das dann auch abspeichern? Bisher sieht es so aus:

Code: Alles auswählen

pfad = "/../Text_einlesen/" t
dateiname = "bla"
datei = pfad+dateiname
in_file = open(datei,"r")
text = in_file.read()
text = text.replace('BLA','Hallo')
in_file.close()
print text
Nun ist das aber nicht abgespeichert?

detlef
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

01detlef hat geschrieben:Nun ist das aber nicht abgespeichert?
Dateipfade solltest du mit os.path.join zusammensetzen.

Es wird nichts abgespeichert weil du nichts speicherst. Um in eine Datei zu schreiben musst du sie zum Schreiben öffnen. Anschließend musst du aktiv Daten hineinschreiben. Eine einfache Zuweisung an text ist und bleibt eine einfache Zuweisung. Dadurch wird keine Dateioperation ausgelöst.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

also das "r" muss ich durch ein "w" ersetzen, aber das replace wird nicht erkannt.
Muss das text = in_file.write() sein, aber da gibt es auch immer einen Fehler.


detlef
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Du musst schon den Vorgang ins Einlesen (im Lesemodus öffnen, einlesen, schließen) und Schreiben (Im Schreibmodus öffnen, schreiben, schließen) unterteilen. Beides zusammen auf einmal geht nicht. Zumindest klingt dein Beitrag so als wolltest du ohne wirklich zu verstehen was da vor sich geht durchs Ersetzen einiger Stellen im Code alles zum Laufen bringen.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

aber ich verstehe nicht, wieso das so falsch ist:

Code: Alles auswählen

pfad = "/home/python/Text_einlesen/" # aktuelles verzeichnis einbauenv
dateiname = "tbla"
datei = pfad+dateiname
in_file = open(datei,"w")   #öffnen
text = text.replace('DeformedCoordinates.nc','Hallo') # ersetzen/schreiben
in_file.close() #schließen
detlef
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

webspider hat es doch bereits beschrieben:

1) Datei zum Lesen öffnen, den gesamten Inhalt einlesen und Datei wieder schließen
2) Die Ersetzungen durchführen
3) Datei zum Schreiben öffnen, neuen Text mit den Ersetzungen schreiben und Datei wieder schließen

Das ganze Schließen kannst du dir sparen, wenn du das with-Statement verwendest.
Das Leben ist wie ein Tennisball.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Gehe doch bitte deinen Code Buchstabe für Buchstabe durch und erläutere ihn, dann wirst du unsere Hinweise (und hoffentlich auch den bisher fabrizierten Code) verstehen können.
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Okay,

also ich habe das nun nochmal versucht und kommentiert:

Code: Alles auswählen

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

pfad = "/.../" # aktuelles verzeichnis einbauenv
dateiname = "..para"
datei = pfad+dateiname
in_file = open(datei,"r") #datei wird zum lesen geöffnet
text = in_file.read() # inhalt wird eingelesen
in_file.close() #datei wird geschlossen

text = text.replace('Bla','Hallo') # ersetzung durchführen


in_file = open(datei,"w") # datei zum schreiben öffnen
text = in_file.write(text) #neuen text schreiben
in_file.close() # datei schließen
    
Das funktioniert nun alles, aber kann ich nun den Text, der ersetzt werden soll, als Variable definieren? Das ganze soll eine Schleife werden und der Text der ersetzt werden soll, ändert sich bei jedem Durchlauf.

Code: Alles auswählen

text = text.replace('test1','Ersatz1') 
und im zweiten Durchlauf
text = text.replace('test2','Ersatz2')
detlef
Zuletzt geändert von 01detlef am Mittwoch 18. April 2012, 07:09, insgesamt 1-mal geändert.
BlackJack

@01detlef: Zum zusammensetzen von Pfadangaben sollte man `os.path.join()` statt ``+`` verwenden.

Und die vorletzte Zeile enthält Unsinn. Was denkst Du denn was dort an den Namen `text` gebunden wird?
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

wieso sollte man den Path mit join zusammenbauen? Und was meinst du in der vorletzten Zeile?

detlef
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Weil es zuverlässiger funktioniert (über alle Plattformen hinweg, kann dir die Schrägstriche vollkommen ersparen, erleichtert die Arbeit mit vom Nutzer eingegebenen Pfaden, Leute die über den Code schauen erkennen direkt, dass du da Pfade verbindest) als ihn von Hand zu verketten. Und die vorletzte Zeile sieht so aus als würdest du erwarten, dass der Schreibvorgang dir etwas zurückgibt, was du an den Namen ``text``binden möchtest. Tut er aber nicht. Wieso auch. Sollte es ein Problem geben (wie zum Beispiel eine nicht mehr existente Datei), wird dir schon eine Exception um die Ohren fliegen.

Zu deiner anderen Frage: Was hindert dich daran?
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Okay,

vielen Dank. ich bin nun dabei die Schleife zu erstellen und bräuchte dazu eine Idee. Es gib in einerm Ordner mehrere Dateien, die eingelesen werden sollen. Ich möchte eine while-Schleife verwenden, aber ich komme nicht so ganz auf eine "Bedingung" für die Schleife.

Also die Dateien sind test-1, test-2 usw. , wie könnte ich dann die Bedingung definieren? Ich habe nicht so recht eine Idee.
Es ist vorher nicht klar, wieviele test-n es gibt, deshalb dachte ich an while.
detlef
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wieso soll es eine `while`-Schleife sein?

Auch wenn Du nicht wirklich präzise angibst, was Du genau machen willst, so gehe ich davon aus, dass Du Dateien nach einem Filter innerhalb eines Verzeichnisses (oder gar rekursiv) aussieben und irgend wie "behandeln" willst? In diesem Falle ist die Anzahl der Dateien *begrenzt* (durch das Dateisystem) und es bietet sich an, eine `for`-Schleife zu verwenden.

Du solltest Dir mal das `glob`-Modul und / oder `os.walk` in Kombination mit `fnmatch` angucken. Da gibt es iirc sogar konkrete Beispiele, wie man diese Funktionen in einer (for-)Schleife benutzt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

genau, also es sind in einem Ordner z.b. Dateien mit dem Titeln Datei-1.dat, Datei-2.dat, Datei-3.dat usw.; Die Anzahl solcher Dateien ist unterschiedlich und aus diesem Grund dachte ich an eine while-Schleife. Die Dateien sollen nacheinander geladen werden und ein Satz ersetzt werden. Also der Code von weiter oben soll in der Schleife auch Verwendung finden.

Weisst du, wo das Beispiel ist? Ich konnte es nicht finden.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

In der Doku zu `glob` sollte es Dir schnell ins Auge fallen, wieso man da mit einer `for`-Schleife besser fährt ;-)

Probiere die reine Anwendung von `glob` doch mal aus!
01detlef hat geschrieben: Weisst du, wo das Beispiel ist? Ich konnte es nicht finden.
In der Doku zu `os.walk` steht das Beispiel. Das brauchst Du aber ja nur, wenn Du rekursiv Dateien suchen willst; dann am besten in Kombi mit dem `fnmatch`-Modul für das Ausfiltern der gewünschten Dateinamen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
01detlef
User
Beiträge: 105
Registriert: Montag 10. Mai 2010, 21:59

Hallo,

also ist es möglich, dass ich erstmal mit

Code: Alles auswählen

import glob
glob.glob('*.nc'
alle Dateien auflisten lasse. Soweit okay. Kann man nun sagen, dass man die in einer Liste speichert und dann in einer Schleife (über den Index) aufruft? Weil wenn ich das glob.glob in der Schleife immer Aufrufe, weiss ich nicht, wie "das nächste File" genommen werden kann?!

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

Dir fehlen anscheinend die absoluten Grundlagen! Arbeite doch mal das offizielle Tutorial durch; zumindest so weit, dass Du mit den grundlegenden Datenstrukturen vertraut bist.

Zudem kannst Du doch mal in einer Python-Shell (hier IPython) experimentieren:

Code: Alles auswählen

In [17]: from glob import glob

In [19]: glob("*.py")
Out[19]: ['classymenu.py', 'metamenu.py', 'simplemenu.py', 'submenu.py']

In [20]: res = glob("*.py")

In [21]: type(res)
Out[21]: builtins.list

In [23]: for filename in glob("*.py"):
    print("Hier kann ich tolles mit '{}' anstellen.".format(filename))
   ....:     
Hier kann ich tolles mit 'classymenu.py' anstellen.
Hier kann ich tolles mit 'metamenu.py' anstellen.
Hier kann ich tolles mit 'simplemenu.py' anstellen.
Hier kann ich tolles mit 'submenu.py' anstellen.
Wie man in [21] erkennt, gibt `glob.glob` also ein Listen-Objekt zurück. Damit zu hantieren sind absolute Grundlagen! Oder hast Du so eine Schleife wie in [23] noch nie gesehen? Wenn nein, befolge meinen Rat dringendst! ;-)

Benutze immer eine Shell, um erst einmal mit einem Modul vertraut zu werden. Du wirst sicherlich zugeben, dass das jetzt nicht besonders schwierig war, was ich da eingetippt habe, oder?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten