2010-04-16 17 views
49

In Python, wenn shutil.rmtree über einen Ordner ausgeführt wird, der eine schreibgeschützte Datei enthält, wird die folgende Ausnahme gedruckt wird:shutil.rmtree nicht unter Windows mit ‚Zugriff verweigert‘

File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 216, in rmtree 
    rmtree(fullname, ignore_errors, onerror) 
File "C:\Python26\lib\shutil.py", line 221, in rmtree 
    onerror(os.remove, fullname, sys.exc_info()) 
File "C:\Python26\lib\shutil.py", line 219, in rmtree 
    os.remove(fullname) 
WindowsError: [Error 5] Access is denied: 'build\\tcl\\tcl8.5\\msgs\\af.msg' 

in Dateieigenschaften suchen Dialog Ich habe festgestellt, dass die Datei af.msg schreibgeschützt ist.

So ist die Frage: Was ist die einfachste Abhilfe/fix, um dieses Problem zu bekommen - da meine Absicht ist, ein Äquivalent von rm -rf build/ aber unter Windows zu tun? (Ohne Werkzeuge von Drittanbietern wie UnxUtils oder Cygwin verwenden zu müssen - wie dieser Code ausgerichtet ist auf einem nackten Windows ausgeführt werden, installieren Sie mit Python 2.6 w/PyWin32 installiert)

+4

'shuthil.rmtree' verwendet' os.remove', um Dateien zu entfernen. 'os.remove' entfernt nur lesbare Dateien (zumindest unter Unix). 'os.remove' kann die Datei unter Windows nicht entfernen, wenn sie verwendet wird. – jfs

+0

mögliches Duplikat von [Verzeichnis in Python löschen] (http://stackoverflow.com/questions/1889597/deleting-directory-in-python) – mozzbozz

Antwort

63

prüfen diese Frage aus:

What user do python scripts run as in windows?

Offenbar ist die Antwort, die Datei/den Ordner zu ändern, um nicht schreibgeschützt zu sein, und es dann zu entfernen.

Hier onerror() Handler von pathutils.py erwähnt von @Sridhar Ratnakumar in den Kommentaren:

def onerror(func, path, exc_info): 
    """ 
    Error handler for ``shutil.rmtree``. 

    If the error is due to an access error (read only file) 
    it attempts to add write permission and then retries. 

    If the error is for another reason it re-raises the error. 

    Usage : ``shutil.rmtree(path, onerror=onerror)`` 
    """ 
    import stat 
    if not os.access(path, os.W_OK): 
     # Is the error an access error ? 
     os.chmod(path, stat.S_IWUSR) 
     func(path) 
    else: 
     raise 
+1

Heh. Ich habe gerade den 'Onerror'-Handler unter http://www.voidspace.org.uk/downloads/pathutils.py entdeckt. –

+0

.. entdeckte das über http://trac.pythonpaste.org/pythonpaste/ticket/359 –

+1

obwohl In den Kommentaren zu dieser Antwort heißt es: "Ändere die Datei/den Ordner so, dass sie nicht schreibgeschützt ist". Ich habe den Zugriff auf schreibgeschützte Ordner weiterhin verweigert. [This] (http://stackoverflow.com/a/1889686/116047) Implementierung funktionierte jedoch. – Pakman

17

Ich würde Ihre eigene rmtree mit os.walk sagen implementieren, die os.chmod durch die Verwendung auf jedem Dateizugriff gewährleistet, bevor Sie versuchen, es zu löschen.

Etwas Ähnliches (nicht getestet):

import os 
import stat 

def rmtree(top): 
    for root, dirs, files in os.walk(top, topdown=False): 
     for name in files: 
      filename = os.path.join(root, name) 
      os.chmod(filename, stat.S_IWUSR) 
      os.remove(filename) 
     for name in dirs: 
      os.rmdir(os.path.join(root, name)) 
    os.rmdir(top)  
+0

Das ist fast richtig - Windows unterstützt nur 'stat.S_IWRITE' (was Sie sowieso wollen) - http: // docs. python.org/library/os.html#os.chmod –

+0

Ich habe getestet, dass 'os.chmod (filename, stat.S_IWUSR)' das schreibgeschützte Flag entfernt hat, also funktioniert es unter WinXP. Und in Anbetracht dessen, was die Dokumentation über 'stat.S_IWRITE' sagt:" Unix V7 Synonym für S_IWUSR "(http://docs.python.org/library/stat.html#stat.S_IWRITE), denke ich über meinen Code nach ist sowieso richtig. – Epcylon

+0

Großartig, mit zu langen Dateipfaden scheint das der einzige Weg zu sein. Eine Empfehlung, shutil.rmtree zu übernehmen oder zu ändern. – Anthony

5

Nun, die markierte Lösung nicht für mich arbeiten ... diese stattdessen tat

os.system('rmdir /S /Q "{}"'.format(directory)) 
0
shutil.rmtree(path,ignore_errors=False,onerror=errorRemoveReadonly) 
def errorRemoveReadonly(func, path, exc): 
    excvalue = exc[1] 
    if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES: 
     # change the file to be readable,writable,executable: 0777 
     os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) 
     # retry 
     func(path) 
    else: 
     raiseenter code here 

Wenn IGNORE_ERRORS ist gesetzt, Fehler werden ignoriert; Wenn onerror gesetzt ist, wird es aufgerufen, um den Fehler mit Argumenten (func, path, exc_info) zu behandeln, wobei func os.listdir, os.remove oder os.rmdir ist; Pfad ist das Argument für diese Funktion, die das Fehlschlagen verursacht hat; und exc_info ist ein Tupel, das von sys.exc_info() zurückgegeben wird. Wenn IGNORE_ERRORS falsch ist und onerror None ist, ist eine Ausnahme raised.enter Code hier

1

Eine einfache Abhilfe ist mit subprocess.call

from subprocess import call 
call("rm -rf build/", shell=True) 

Um alles, was Sie ausführen möchten.

Verwandte Themen