Seite 1 von 2

Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:16
von TheBombTuber
Hallo,

Ich habe ein Problem mit einem Permission Error und wollte diesen mit os.chmod "bekämpfen".

Das Problem welchem ich gegenüberstehen ist, wie kann ich den Pfad aus der Fehlermeldung nutzen um den Fehler zu korrigieren?

Fehlermeldung lautet wie folgt.

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\cpohlmann\Desktop\Python\aft_austauschen.py", line 39, in <module>
    remove_files(path)
  File "C:\Users\cpohlmann\Desktop\Python\aft_austauschen.py", line 20, in remove_files
    shutil.rmtree(os.path.join(path, filename))
  File "C:\Users\cpohlmann\AppData\Local\Continuum\anaconda3\lib\shutil.py", line 513, in rmtree
    return _rmtree_unsafe(path, onerror)
  File "C:\Users\cpohlmann\AppData\Local\Continuum\anaconda3\lib\shutil.py", line 397, in _rmtree_unsafe
    onerror(os.unlink, fullname, sys.exc_info())
  File "C:\Users\cpohlmann\AppData\Local\Continuum\anaconda3\lib\shutil.py", line 395, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 5] Zugriff verweigert: 'C:\\cad\\vwg\\catia\\vwgrclite\\opt\\aft\\3DZP\\3DZP_aft_fileversion.txt'
Den Pfad den ich nutzen möchte ist

Code: Alles auswählen

'C:\\cad\\vwg\\catia\\vwgrclite\\opt\\aft\\3DZP\\3DZP_aft_fileversion.txt'
Aber wie komme ich an den heran?

Schon einmal im Voraus vielen Dank für eure Ideen

Mit freundlichen Grüßen TheBombTuber

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:21
von sls
Du willst den PermissionError abfangen und dann die Rechte auf die Dateien einfach via chmod vergeben? Das würde ich nicht tun. Sinnvoller wäre es, wenn du dem Benutzer der das Skript ausführt die entsprechenden Rechte zuweist diese oder jene Dateien lesen oder bearbeiten zu dürfen.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:22
von sparrow
Schau mal, hier wird erklärt, wie man an die Exception an eine Variable bindet.

Die eigentlich Frage ist aber, wann die Fehlermeldung geworfen wird. Wenn du eine Dateiliste durch gehst, und es dabei zu dem Problem kommt, dann hast du diese Datei ja in der Liste und arbeitest sie gerade ab. Dann ist es vielleicht sinnvoller damit zu arbeiten.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:35
von TheBombTuber
sls hat geschrieben: Montag 21. Januar 2019, 09:21 Du willst den PermissionError abfangen und dann die Rechte auf die Dateien einfach via chmod vergeben? Das würde ich nicht tun. Sinnvoller wäre es, wenn du dem Benutzer der das Skript ausführt die entsprechenden Rechte zuweist diese oder jene Dateien lesen oder bearbeiten zu dürfen.
Das seltsame hierbei ist, dass der Benutzer Vollzugriff auf die Dateien hat und diese manuell auch zu löschen sind. Nur über das Skript lassen sich die Dateien nicht löschen

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:37
von TheBombTuber
sparrow hat geschrieben: Montag 21. Januar 2019, 09:22 Schau mal, hier wird erklärt, wie man an die Exception an eine Variable bindet.

Die eigentlich Frage ist aber, wann die Fehlermeldung geworfen wird. Wenn du eine Dateiliste durch gehst, und es dabei zu dem Problem kommt, dann hast du diese Datei ja in der Liste und arbeitest sie gerade ab. Dann ist es vielleicht sinnvoller damit zu arbeiten.
Ich arbeite hier nur die Obersten Ordner durch und nicht die einzelnen Dateien darunter daher leider der Umweg über den Error um den Fehler zu beheben. Ich werde mir mal die Dokumentation durchlesen vielleicht habe ich da was überlesen beim ersten durchgehen

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:39
von Sirius3
@TheBombTuber: die Exceptions unter Windows haben ein filename-Attribut.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 09:58
von TheBombTuber
Sirius3 hat geschrieben: Montag 21. Januar 2019, 09:39 @TheBombTuber: die Exceptions unter Windows haben ein filename-Attribut.
@Sirius könntest du mir einmal ausführen was genau du damit sagen möchtest stehe grade etwas auf dem Schlauch

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 10:12
von Sirius3
Weißt Du was ein Objekt in Python ist, und dass Objekte Attribute haben? Weißt Du was ein Exception-Objekt ist, und wie Du es abfangen kannst?
Zeig doch den Code, um den es gerade geht.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 10:24
von TheBombTuber
Sirius3 hat geschrieben: Montag 21. Januar 2019, 10:12 Weißt Du was ein Objekt in Python ist, und dass Objekte Attribute haben? Weißt Du was ein Exception-Objekt ist, und wie Du es abfangen kannst?
Zeig doch den Code, um den es gerade geht.
Hier ist der Code in dem der Permission Error abgefangen werden soll

Code: Alles auswählen

def remove_files(path):
    for filename in os.listdir(path):
        try:
            print(filename + " wird entfernt")
            time.sleep(0.5)
            shutil.rmtree(os.path.join(path, filename))
        except FileNotFoundError:
            print("Zu Löschende Datei konnte nicht gefunden werden")
        except PermissionError as err:
            print(err)
            os.chmod(hier pfad, stat.S_IWRITE)
            break
Hier ist der gesamte Code

Code: Alles auswählen

import os
import shutil
import time
import stat

benutzer = os.getlogin()
path_new = r"\\srv-23v-isea-01\temp\CPO\aft_GRCLITE"
def remove_files(path):
    for filename in os.listdir(path):
        try:
            print(filename + " wird entfernt")
            time.sleep(0.5)
            shutil.rmtree(os.path.join(path, filename))
        except FileNotFoundError:
            print("Zu Löschende Datei konnte nicht gefunden werden")
        except PermissionError as err:
            print(err)
            os.chmod(hier pfad, stat.S_IWRITE)
            break

            
def add_files(path_new):
    for filename_new in os.listdir(path_new):
        time.sleep(2)
        print(os.path.join(filename_new + " wird eingefügt"))
        shutil.copytree(os.path.join(path_new, filename_new), os.path.join(path, filename_new))

for path in[r"C:\cad\vwg\catia\vwgrclite\opt\aft",
		r"C:\catiav5\vwg\catia\vwgrclite\opt\aft",]:
    if os.path.isdir(path):
        print("Hallo " + benutzer)
        print('Bitte beachte, dass beim Forfahren Catia beendet wird!!\nBitte alle Daten speichern und anschließend "Enter" drücken')
        close = input()
        if close == '':
            os.system("taskkill /f /im CNEXT.exe")
            print("Die alten Additionals werden entfernt.")
            remove_files(path)
            print("Alle Datein erfolgreich entfernt")
            time.sleep(1)
            os.system("cls")
            add_files(path_new)
            os.system("cls")
            print("Der Austausch ist abgeschlossen.\nZum beenden Enter drücken.")
            input()
        else:
            print('Programm wird beendet')

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 10:45
von Sirius3
Du hast also schon ein `err`-Objekt, und was ist Dir dann an Attribut nicht klar?

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 12:10
von __blackjack__
@TheBombTuber: Ansonsten könnte das `onerror`-Argument von `shutil.rmtree()` auch für Dich interessant sein. Da kannst Du eine Funktion übergeben die im Fehlerfall drei Argumente bekommt, unter anderem den Pfad und Typ, Wert, und Traceback der Ausnahme. Der Vorteil hierbei ist, das `rmtree()` dabei nicht abgebrochen wird. Dass heisst Du kannst versuchen in dem Aufruf der Funktion, die Du dort übergibst, das Problem zu beseitigen, und wenn die zu `rmtree()` zurückkehrt, dann läuft `rmtree()` weiter durch.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 12:29
von TheBombTuber
Sirius3 hat geschrieben: Montag 21. Januar 2019, 10:45 Du hast also schon ein `err`-Objekt, und was ist Dir dann an Attribut nicht klar?
Die Ausgabe aus dem 'err'-Objekt lautet

Code: Alles auswählen

[WinError 5] Zugriff verweigert: 'C:\\cad\\vwg\\catia\\vwgrclite\\opt\\aft\\3DZP\\3DZP_aft_fileversion.txt'
Und die müsste ich ja nun noch auf den Pfad herunterbrechen.
Momentan versuche ich es "einfach" mit einer Beschränkung auf auf die Buchstaben mit dem [ ]-Operator zu umgehen.

Sobald ich da etwas brauchbares habe werde ich es posten

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 12:55
von __blackjack__
@TheBombTuber: Es geht nicht um die Ausgabe des `err`-Objekts als Zeichenkette sondern um die Attribute von dem Objekt.

Fang bloss nicht an auf der Zeichenkettenrepräsentation zu operieren, die kann (und wird in diesem Fall sogar) auf anderen Betriebssystemen anders aussehen. Selbst unter Windows hängt sie ja offensichtlich von der Spracheinstellung des Systems ab, denn bei einem englischsprachigen Windows wird da sicher nicht 'Zugriff verweigert' stehen.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 13:40
von TheBombTuber
__blackjack__ hat geschrieben: Montag 21. Januar 2019, 12:55 @TheBombTuber: Es geht nicht um die Ausgabe des `err`-Objekts als Zeichenkette sondern um die Attribute von dem Objekt.

Fang bloss nicht an auf der Zeichenkettenrepräsentation zu operieren, die kann (und wird in diesem Fall sogar) auf anderen Betriebssystemen anders aussehen. Selbst unter Windows hängt sie ja offensichtlich von der Spracheinstellung des Systems ab, denn bei einem englischsprachigen Windows wird da sicher nicht 'Zugriff verweigert' stehen.
@__blackjack__: Dann muss ich doch aber vorher noch ein Klasse für das "err"-Objekt implementieren um dann mit Attributen arbeiten zu können oder liege ich falsch?

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 13:56
von sparrow
Das wunderbare an Python ist, dass man viel im Interpreter selbst herausfinden kann.
Zum Beispiel erfährst du mit type(err) um was für ein Objekt es sich handelt. Und mit help(err) bekommst du sogar detailliert Informationen und Hilfe.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 14:41
von TheBombTuber
Momentan löse ich das Problem über Zeichenketten
(Sollte vorerst auch kein Problem sein da alle Systeme gleiche Grundeinstellungen haben)

Code: Alles auswählen

# -*- coding: utf-8 -*-
import os
import shutil
import time
import stat

benutzer = os.getlogin()
path_new = r"\\srv-23v-isea-01\temp\CPO\aft_GRCLITE"
suchpfad = r"C\w"
def remove_files(path):
    for filename in os.listdir(path):
        while True:
            try:
                print(filename + " wird entfernt")
                shutil.rmtree(os.path.join(path, filename))
            except FileNotFoundError:
                print("Zu Löschende Datei konnte nicht gefunden werden")
                break
            except PermissionError as err:
                help(err)
                x = str(err)
                umgehen = x[34:-1]
                os.chmod(umgehen, stat.S_IWRITE)
                break
            break
        break

            
def add_files(path_new):
    for filename_new in os.listdir(path_new):
        time.sleep(2)
        print(os.path.join(filename_new + " wird eingefügt"))
        shutil.copytree(os.path.join(path_new, filename_new), os.path.join(path, filename_new))

for path in[r"C:\cad\vwg\catia\vwgrclite\opt\aft",
		r"C:\catiav5\vwg\catia\vwgrclite\opt\aft",]:
    if os.path.isdir(path):
        print("Hallo " + benutzer)
        print('Bitte beachte, dass beim Forfahren Catia beendet wird!!\nBitte alle Daten speichern und anschließend "Enter" drücken')
        close = input()
        if close == '':
            os.system("taskkill /f /im CNEXT.exe")
            print("Die alten Additionals werden entfernt.")
            time.sleep(2)
            remove_files(path)
            print("Alle Datein erfolgreich entfernt")
            time.sleep(2)
            os.system("cls")
            add_files(path_new)
            os.system("cls")
            print("Der Austausch ist abgeschlossen.\nZum beenden Enter drücken.")
            input()
        else:
            print('Programm wird beendet')
Ich werde versuchen es vernünftig mit Attributen zu lösen muss mich da aber denke ich erst einmal intensiver einlesen.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 14:48
von __blackjack__
@TheBombTuber: Die Ausnahme ist doch bereits ein Exemplar einer Klasse, die Du sogar kennst, denn die hast Du ja selbst beim ``except`` angegeben: `PermissionError`. Neben dem Hinweis von sparrow wie man Infos live von dem Objekt bekommen kann, kannst Du natürlich auch in der Python-Dokumention nachlesen was es mit diesem Datentyp auf sich hat.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 20:02
von Sirius3
@TheBombTuber: Du scheinst einen zwingen zu wollen, die Musterlösung zu liefern, weil es einem beim Lesen weh tut. Da sind auch einige `breaks` zu viel, womit die while-Schleife auch überflüssig ist:

Code: Alles auswählen

def remove_files(path):
    for filename in os.listdir(path):
        try:
            print("{} wird entfernt".format(filename))
            shutil.rmtree(os.path.join(path, filename))
        except FileNotFoundError:
            print("Zu Löschende Datei konnte nicht gefunden werden")
        except PermissionError as err:
            os.chmod(err.filename, stat.S_IWRITE)

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Montag 21. Januar 2019, 20:16
von __blackjack__
@Sirius3: Wobei das in der Funktion IMHO nix zu suchen hat. Jetzt haben wir eine Funktion um in einem Ordner alle Unterordner zu löschen (und der sollte nur Ordner enthalten, sonst kracht's) und der alle löscht, ausser das rekursive löschen trifft auf einen `PermissionError`. Da werden nur die Rechte geändert und die komplette weitere Löschaktion des Ordners in dem das passiert ist abgebrochen. Ohne das der Aufrufer da etwas von mitbekommt. Wahrscheinlich war die durch die ``break``\s sinnfrei gemachte ``while``-Schleife ein Versuch das so lange zu wiederholen bis wirklich alles in dem Verzeichnis gelöscht ist.

Ich denke ja immer noch etwas mit dem `onerror`-Argument von `rmtree()` ist die sinnvollere Lösung.

Re: Pfad aus Fehlermeldung nutzen

Verfasst: Dienstag 22. Januar 2019, 06:47
von sparrow
@TheBombTuber: Deine Lösung steckt in einer Endlosschleife, sollte sich das Rechteproblem mit dem chmod nicht beseitigen lassen.

Ansonsten tendiere ich wie BJ rmtree() mit onerror.