2011-01-28 9 views
29

Tengo un directorio de solo lectura copiado del directorio controlado por la versión que está bloqueado. enter image description here¿Cómo eliminar el directorio attrib de solo lectura con Python en Windows?

Cuando traté de eliminar este directorio con el comando shutil.rmtree(TEST_OBJECTS_DIR), recibí el siguiente mensaje de error.

WindowsError: [Error 5] Access is denied: 'C:\...\environment.txt' 
  • Q: ¿Cómo puedo cambiar el atributo de todo en su conjunto una estructura de directorios ?

Respuesta

38

Si está utilizando shutil.rmtree, se puede utilizar el miembro onerror de esa función para proporcionar una función que toma tres parametros: función, camino, y la información de excepción. Puede usar este método para marcar archivos de solo lectura como de escritura mientras está eliminando su árbol.

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) 

Ahora, para ser justos, podría llamarse a la función de error por varias razones. El parámetro 'func' puede decirle qué función "falló" (os.rmdir() o os.remove()). Lo que hagas aquí depende de cuán a prueba de balas quieras que sea tu árbol. Si realmente es solo un caso de necesidad de marcar archivos como modificables, podría hacer lo que hice anteriormente. Si quiere tener más cuidado (es decir, determinar si el directorio no puede ser eliminado, o si hubo una violación de compartir en el archivo al intentar eliminarlo), la lógica apropiada debería insertarse en la función on_rm_error() .

+1

¡Genial! Este es un enfoque más dedicado. – YOU

9

No probado, pero sería, algo así como habilitar el acceso de escritura.

import os, stat 

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

Es posible que tenga que combinar con os.walk para hacer que todo escriba habilitado. algo así como

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) 
+0

Más detalles aquí, también: http://techarttiki.blogspot.com/2008/08/read-only-windows-files-with-python.html – payne

4

El método que he utilizado es hacer:

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

Antes de que alguien salta sobre mí, sé que esto es terriblemente un-Pythonic, pero es posiblemente más simple que las respuestas más tradicionales dadas anteriormente, y ha sido confiable.

No estoy seguro de qué ocurre con los atributos de lectura/escritura en los directorios. Pero no ha sido un problema todavía.

+0

Esta solución funciona en Windows (siempre que exista attrib.exe) y no requiere módulos externos de python. – Nils

+0

la solución es excelente, y la considero más eficiente – Kewin

+0

@Nils Ninguna de las otras soluciones ofrecidas hasta ahora requieren ningún módulo externo de Python tampoco. EDITAR: Ok, me perdí las cosas win32con. – antred

2
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) 

copia de: http://code.activestate.com/recipes/303343-changing-file-attributes-on-windows/

4

La respuesta aceptada es casi correcta, pero podría fallar en caso de un subdirectorio de sólo lectura.

La función se da como argumento para el controlador rmtree de onerror.

que sugeriría:

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) 

En caso de que la función falla de nuevo, se puede ver la razón, y continuar con la eliminación.

Cuestiones relacionadas