Seite 1 von 1
Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 09:58
von recnice
Hallo,
ich möchte ein Script schreiben, dass eine bestimmtes Programm startet, welches aber ein bestimmtes Inputfile braucht.
Mein Script soll überprüfen ob dies Inputfile vorhanden ist, ist dieses nicht vorhanden wird dass Script beendet.
Für meinen ersten Versuch habe ich einfach eine if-else Abfrage genommen:
Code: Alles auswählen
import subprocess,os,sys
ElmerCaseFile = "fsi.sif"
ort = os.getcwd()
dateien_aktueller_ort = os.listdir(ort)
def Elmer_run():
global ElmerCaseFile
if ElmerCaseFile not in dateien_aktueller_ort:
sys.exit("\n%s doesn't exist\n" %(ElmerCaseFile))
else:
cmd_elmer = 'ElmerSolver ' + ElmerCaseFile + ' > log'
print "Starte ELMER"
Elmer = subprocess.Popen(cmd_elmer,shell=True)
Elmer.wait()
print "Elmer beendet"
# check for Error-Termination
log = open("log","r")
lines = log.read().split()
if 'ERROR::' in lines:
sys.exit ("ELMER: ERROR TERMINATION")
Dies funktioniert auch. Als nächstes habe ich mir gedacht, ich versuche diese if-else Abfrage durch eine "Exception" zu ersetzen:
Code: Alles auswählen
def Elmer_run():
global ElmerCaseFile
try:
cmd_elmer = 'ElmerSolver ' + ElmerCaseFile + ' > log'
print "Starte ELMER"
Elmer = subprocess.Popen(cmd_elmer,shell=True)
Elmer.wait()
print "Elmer beendet"
# check for Error-Termination
log = open("log","r")
lines = log.read().split()
if 'ERROR::' in lines:
sys.exit ("ELMER: ERROR TERMINATION")
except IOError as error:
sys.exit("\n\n%s: does'n exist !\n" % (ElmerCaseFile))
Dies führt zu der folgenden Ausgabe:
Starte ELMER
Elmer beendet
ELMER: ERROR TERMINATION
Eigentlich sollte der Prozess gar nicht gestartet werden, da ja das Inputfile fehlt.
Erkennt jemand den Fehler?
Gruß
Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 10:10
von snafu
Bist du wirklich ganz sicher, dass die Datei nicht schon existiert? Denn eigentlich dürfte dein Skript bei einer fehlenden Datei tatsächlich nicht die von dir gezeigte Ausgabe zeigen. Genereller Tipp übrigens: Schreibe möglichst nur eine Zeile in den `try`-Block. Dann muss man nicht lange rätseln, wo der abzufangene Fehler auftreten könnte.
//edit: Und, es entstehen keine "Doppeldeutigkeiten", da beim Arbeiten mit Subprozessen unter Umständen auch ein `IOError` auftreten kann.
Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 10:23
von recnice
Hi,
also die Datei existiert definitiv nicht!! Hab sie gelöscht
Also ich muss ( :K ) doch den kompletten Block, den die Funktion ausführen möchte in den try-Teil einfügen.
Vielleicht noch mal konkret was in der Funktion passiert:
1. Starte auf der Konsole "ElmerSolver fsi.sif > log"
2. Wenn Prozess beendet schau in dem log-File nach ob
alles passt.
übrigens im log file steht dann
ERROR:: ElmerSolver: Unable to find input file [fsi.sif], can not execute.
Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 10:51
von snafu
recnice hat geschrieben:Also ich muss ( :K ) doch den kompletten Block, den die Funktion ausführen möchte in den try-Teil einfügen.
Es ist sinnvoller, wenn dein `try`-Block nur die Zeile umgibt (hier offensichtlich die mit `open()`), wo der Fehler erwartet wird. Der restliche Code kann besser vor dem `try` stehen.
Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 11:03
von BlackJack
@recnice: Welche Zeile denkst Du denn sollte den `IOError` auslösen wenn die Datei nicht vorhanden ist. Dein (zweites) *Python-Programm* greift doch gar nicht auf die Datei zu, demzufolge kann auch innerhalb von Python keine Ausnahme ausgelöst werden. Das *externe* ``ElmerSolver``-Programm ist doch im zweiten Beispiel das erste und einzige Programm das auf die Datei zugreift — und dann halt fest stellt, dass die Datei nicht existiert.
Weitere Anmerkungen:
`os.path.exists()` existiert.
``global`` gehört in der Regel in kein vernünftiges Programm und hier ist es auch noch völlig unnötig.
Das Zusammenbauen von einem Kommando als eine Zeichenkette um dann `Popen()` mit ``shell=True`` aufzurufen sollte man vermeiden. Das lässt sich im vorliegenden Beispiel auch komplett ohne den Umweg über eine Shell lösen.
Dateien sollte man mit der ``with``-Anweisung öffnen oder mindestens explizit wieder schliessen.
Die Logdatei komplett einlesen, in Zeilen austeilen, und dann darin suchen, ist deutlich zu umständlich. Zum Lesen geöffnete Textzeilen sind iterierbar, und zwar liefern sie die Textzeilen. Und mit dem ``in``-Operator kann man testen ob ein Element in einem iterierbaren Objekt enthalten ist.
Brauchst Du die Logdatei noch anderweitig? Falls nein, sollte man die ersatzlos streichen und gleich innerhalb des Programms die Ausgabe von ``ElmerSolver`` verarbeiten. Dann könnte man das zum Beispiel auch mehrfach starten, ohne dass sie die verschiedenen Inkarnationen gegenseitig die Logdatei überschreiben.
@snafu: Es geht nicht um die Logdatei!
Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 11:14
von recnice
@ Black Jack
Sorry, der Teil gehört natürlich auch zum zweiten Programm dazu:
Meine Intention war, wird das hier ausgeführt
Code: Alles auswählen
cmd_elmer = 'ElmerSolver ' + ElmerCaseFile + ' > log'
und eben "fsi.sif " nicht vorhanden ist, dass eben
Code: Alles auswählen
sys.exit("\n\n%s: does'n exist !\n" % (ElmerCaseFile))
ausgegeben wird.....
Danke für den Hinweis zum einlesen der log-Datei

Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 11:18
von BlackJack
@recnice: Das ändert nichts an meiner Frage oder dem Problem. Solange Du nicht im *Python-Programm* etwas mit der Datei machst, kann innerhalb des Python-Programms auch keine Ausnahme deswegen ausgelöst werden.
Ups, da habe ich wohl die Verarbeitung der Logdatei falsch interpretiert. Du teilst ja gar nicht an Zeilen, sondern generell an „whitespace”-Zeichen. Wäre das denn nötig?
So könnte das aussehen, wenn man die Shell und die Protokolldatei vermeiden möchte (ungetestet):
Code: Alles auswählen
import os
from subprocess import Popen, PIPE
def elmer_run(case_filename):
if not os.path.exist(case_filename):
raise ValueError('%r does not exist' % case_filename)
elmer = Popen(['ElmerSolver', case_filename], stdout=PIPE)
output = list(elmer.stdout)
elmer.wait()
return any(line.startswith('ERROR::') for line in output)
Die Funktion löst eine Ausnahme aus, wenn die Datei nicht existiert und gibt einen Wahrheitswert zurück, je nach dem ob ein Fehler in der Ausgabe von ``ElmerSolver`` stand, oder nicht.
Wenn man die Protokolldatei haben möchte, könnte man sie in der Funktion auch anlegen.
Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 11:20
von snafu
BlackJack hat geschrieben:@recnice: Welche Zeile denkst Du denn sollte den `IOError` auslösen wenn die Datei nicht vorhanden ist. Dein (zweites) *Python-Programm* greift doch gar nicht auf die Datei zu, demzufolge kann auch innerhalb von Python keine Ausnahme ausgelöst werden.
Achso, jetzt versteh ich erstmal. Es geht ihm ja garnicht um die Datei `log`.

Re: Exception funktioniert nicht
Verfasst: Freitag 13. Januar 2012, 11:39
von recnice
ja dass sieht schon profi-mäßig aus
Ok hab's nun verstanden warum die Exception nicht funktioniert hat!!
Nochmals Danke !!