shutil.rmtree no eliminará archivos de solo lectura en Windows. ¿Hay un equivalente en python de "rm -rf"? ¿Por qué, oh, por qué es esto un dolor?

38
kevin cline 11 dic. 2009 a las 20:29

6 respuestas

La mejor respuesta

shutil.rmtree puede tomar una función de manejo de errores que se llamará cuando tenga problemas para eliminar un archivo. Puede usar eso para forzar la eliminación de los archivos problemáticos.

Inspirado por http://mail.python.org/pipermail/tutor/2006 -Junio / 047551.html y http://techarttiki.blogspot.com/2008/08/read-only-windows-files-with-python.html:

import os
import stat
import shutil

def remove_readonly(func, path, excinfo):
    os.chmod(path, stat.S_IWRITE)
    func(path)

shutil.rmtree(top, onerror=remove_readonly)

(No he probado ese fragmento, pero debería ser suficiente para comenzar)

47
Éric Araujo 9 may. 2014 a las 18:13

Hay un comentario en el sitio ActiveState que dice:

shutil.rmtree tiene sus defectos. Aunque es cierto que puede usar shutil.rmtree () en muchos casos, hay algunos casos en los que no funciona. Por ejemplo, shutil.rmtree () no puede eliminar los archivos que están marcados como de solo lectura en Windows.

Al importar los módulos win32api y win32con de PyWin32 y agregar una línea como "win32api.SetFileAttributes (path, win32con.FILE_ATTRIBUTE_NORMAL" a la función rmgeneric (), este obstáculo se puede superar. Utilicé este enfoque para solucionar el script hot-backup.py de Subversion 1.4 para que funcione en Windows. Gracias por la receta.

No uso Windows, así que no puedo verificar si esto funciona o no.

3
ire_and_curses 11 dic. 2009 a las 17:34

Si importa win32api desde PyWin32, puede usar:

win32api.SetFileAttributes(path, win32con.FILE_ATTRIBUTE_NORMAL)

Hacer que los archivos dejen de ser de solo lectura.

4
Paul 11 dic. 2009 a las 17:34

Presumiblemente, esto se solucionará con el lanzamiento de Python 3.5 (actualmente - junio de 2015 - aún en desarrollo) en el sentido de dar una pista sobre esto en la documentación.

Puede encontrar el informe de errores aquí. Y este es el conjunto de cambios correspondiente.

Vea el ejemplo recientemente agregado de los documentos de Python 3.5:

import os, stat
import shutil

def remove_readonly(func, path, _):
    "Clear the readonly bit and reattempt the removal"
    os.chmod(path, stat.S_IWRITE)
    func(path)

shutil.rmtree(directory, onerror=remove_readonly)
3
mozzbozz 16 jun. 2015 a las 10:23

Otra forma es definir rmtree en Windows como

rmtree = lambda path: subprocess.check_call(['cmd', '/c', 'rd', '/s', '/q', path])
4
asmeurer 12 sep. 2014 a las 15:49

Aquí hay una variante de lo que Steve publicó, usa el mismo mecanismo básico, y este está probado :-)

¿Qué usuario ejecutan los scripts de Python como en Windows?

2
Community 23 may. 2017 a las 11:54