web-dev-qa-db-fra.com

Comment supprimer le répertoire attrib en lecture seule avec Python dans Windows?

J'ai un répertoire en lecture seule copié à partir du répertoire contrôlé par version qui est verrouillé. enter image description here

Lorsque j'ai essayé de supprimer ce répertoire avec la commande shutil.rmtree(TEST_OBJECTS_DIR), j'ai reçu le message d'erreur suivant.

WindowsError: [Error 5] Access is denied: 'C:\...\environment.txt'
  • Q: Comment puis-je changer l'attribut de tout dans une structure de répertoires entier?
40
prosseek

Si vous utilisez shutil.rmtree, vous pouvez utiliser le membre onerror de cette fonction pour fournir une fonction qui prend trois paramètres: fonction, chemin et informations d'exception. Vous pouvez utiliser cette méthode pour marquer les fichiers en lecture seule comme accessibles en écriture lorsque vous supprimez votre arborescence.

import os, shutil, stat

def on_rm_error( func, path, exc_info):
    # path contains the path of the file that couldn't be removed
    # let's just assume that it's read-only and unlink it.
    os.chmod( path, stat.S_IWRITE )
    os.unlink( path )

shutil.rmtree( TEST_OBJECTS_DIR, onerror = on_rm_error )

Maintenant, pour être juste, la fonction d'erreur peut être appelée pour diverses raisons. Le paramètre 'func' peut vous dire quelle fonction "a échoué" (os.rmdir () ou os.remove ()). Ce que vous faites ici dépend de la résistance aux balles que vous souhaitez que votre rmtree soit. Si c'est vraiment juste un cas de besoin de marquer des fichiers comme inscriptibles, vous pouvez faire ce que j'ai fait ci-dessus. Si vous voulez être plus prudent (c'est-à-dire déterminer si le répertoire ne doit pas être supprimé, ou s'il y a eu une violation de partage sur le fichier en essayant de le supprimer), la logique appropriée devra être insérée dans la fonction on_rm_error () .

51
Mark

Non testé mais ce serait, quelque chose comme pour activer l'accès en écriture.

import os, stat

os.chmod(ur"file_path_name", stat.S_IWRITE)

Vous devrez peut-être combiner avec os.walk pour que tout soit activé en écriture. quelque chose comme

for root, dirs, files in os.walk(ur'root_dir'):
    for fname in files:
        full_path = os.path.join(root, fname)
        os.chmod(full_path ,stat.S_IWRITE)
10
YOU

La méthode que j'ai utilisée est de faire:

if os.path.exists(target) :
    subprocess.check_call(('attrib -R ' + target + '\\* /S').split())
    shutil.rmtree(target)

Avant que quelqu'un ne me saute dessus, je sais que c'est terriblement anti-Pythonique, mais c'est peut-être plus simple que les réponses plus traditionnelles données ci-dessus, et a été fiable.

Je ne sais pas ce qui se passe concernant les attributs de lecture/écriture sur les répertoires. Mais ce n'est pas encore un problème.

5
Mike Gleen

La réponse acceptée est presque exacte, mais elle pourrait échouer dans le cas d'un sous-répertoire en lecture seule.

La fonction est donnée en argument au gestionnaire rmtree de onerror.

Je voudrais suggerer:

import os, shutil, stat

def remove_readonly(fn, path, excinfo):
    try:
        os.chmod(path, stat.S_IWRITE)
        fn(path)
    except Exception as exc:
        print "Skipped:", path, "because:\n", exc

shutil.rmtree(TEST_OBJECTS_DIR, onerror=remove_readonly)

Si la fonction échoue à nouveau, vous pouvez voir la raison et continuer la suppression.

5
Tomasz Gandor
import win32con, win32api,os

file='test.txt'

#make the file hidden
win32api.SetFileAttributes(file,win32con.FILE_ATTRIBUTE_HIDDEN)

#make the file read only
win32api.SetFileAttributes(file,win32con.FILE_ATTRIBUTE_READONLY)

#to force deletion of a file set it to normal
win32api.SetFileAttributes(file, win32con.FILE_ATTRIBUTE_NORMAL)
os.remove(file)

copie depuis: http://code.activestate.com/recipes/303343-changing-file-attributes-on-windows/

4
zoumi