Exception funktioniert nicht

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
recnice
User
Beiträge: 45
Registriert: Sonntag 20. März 2011, 12:10

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ß
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
recnice
User
Beiträge: 45
Registriert: Sonntag 20. März 2011, 12:10

Hi,

also die Datei existiert definitiv nicht!! Hab sie gelöscht :lol:

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.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
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!
recnice
User
Beiträge: 45
Registriert: Sonntag 20. März 2011, 12:10

@ Black Jack

Sorry, der Teil gehört natürlich auch zum zweiten Programm dazu:

Code: Alles auswählen

import subprocess,os,sys
ElmerCaseFile         = "fsi.sif"
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 :wink:
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.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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`. :o
recnice
User
Beiträge: 45
Registriert: Sonntag 20. März 2011, 12:10

ja dass sieht schon profi-mäßig aus :lol:


Ok hab's nun verstanden warum die Exception nicht funktioniert hat!!

Nochmals Danke !!
Antworten