Pfad aus Fehlermeldung nutzen

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.
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

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.
When we say computer, we mean the electronic computer.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

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.
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@TheBombTuber: die Exceptions unter Windows haben ein filename-Attribut.
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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')
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast also schon ein `err`-Objekt, und was ist Dir dann an Attribut nicht klar?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

__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?
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

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.
TheBombTuber
User
Beiträge: 41
Registriert: Samstag 9. September 2017, 15:48

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@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)
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

@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.
Antworten