shutil.rmtree ne fonctionne pas sous Windows avec 'Accès refusé'

En Python, lors de l'exécution de shutil.rmtree sur un dossier qui contient un fichier en lecture seule, l'exception suivante est imprimée:

 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 216, in rmtree
   rmtree(fullname, ignore_errors, onerror)
 File "C:Python26libshutil.py", line 221, in rmtree
   onerror(os.remove, fullname, sys.exc_info())
 File "C:Python26libshutil.py", line 219, in rmtree
   os.remove(fullname)
WindowsError: [Error 5] Access is denied: 'buildtcltcl8.5msgsaf.msg'

recherche dans la boîte de dialogue Propriétés du fichier j'ai remarqué que le fichier af.msg est réglé pour être lu seulement.

alors la question Est: qu'est - ce que le le plus simple contourner/corriger pour contourner ce problème-étant donné que mon intention est de faire un équivalent de rm -rf build/ mais sur Windows? (sans avoir à utiliser des outils tiers comme unxutils ou cygwin-car ce code est destiné à être exécuté sur une installation Windows avec Python 2.6 w/ PyWin32 installé)

53
demandé sur BartoszKP 2010-04-17 01:57:55

5 réponses

Vérifiez cette question:

quel utilisateur les scripts python fonctionnent-ils sous windows?

apparemment, la réponse est de changer le fichier / dossier pour ne pas être en lecture seule et puis de le supprimer.

Voici onerror() handler de pathutils.py mentionné par @Sridhar Ratnakumar dans les commentaires:

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
67
répondu Justin Peel 2017-05-23 12:34:44

je dirais implémenter votre propre rmtree avec os.marcher qui assure l'accès en utilisant os.chmod sur chaque fichier avant d'essayer de le supprimer.

quelque chose comme ceci (non testé):

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)      
21
répondu Epcylon 2015-06-27 00:09:40

Eh bien, la solution marquée n'a pas fonctionné pour moi... fait ceci à la place:

os.system('rmdir /S /Q "{}"'.format(directory))
7
répondu AlexeiOst 2016-09-30 14:20:15
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

si ignore_errors est défini, les erreurs sont ignorées; sinon, si onerror est défini, il est appelé à gérer l'erreur avec des arguments (func, chemin, exc_info) où func est os.listdir, os.supprimer, ou de l'os.rmdir; path est l'argument de cette fonction qui a causé son échec; et exc_info est un tuple retourné par sys.exc_info (). Si du paramètre ignore_errors est faux et onerror est nul, une exception est soulevée.entrer le code ici

0
répondu RongyanZheng 2015-02-12 11:53:53

une solution simple est d'utiliser subprocess.call

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

pour exécuter tout ce que vous voulez.

0
répondu besil 2015-11-20 10:02:00