remove - shutil python
shutil.rmtree falla en Windows con ''Acceso denegado'' (5)
Bueno, la solución marcada no funcionó para mí ... hizo esto en su lugar:
os.system(''rmdir /S /Q "{}"''.format(directory))
En Python, cuando se ejecuta shutil.rmtree
sobre una carpeta que contiene un archivo de solo lectura, se imprime la siguiente excepción:
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''
Al mirar en el cuadro de diálogo Propiedades de archivo, noté que el archivo af.msg
está configurado para ser de solo lectura.
Entonces, la pregunta es: ¿cuál es la solución / solución más simple para evitar este problema, dado que mi intención es hacer un equivalente de rm -rf build/
pero en Windows? (sin tener que usar herramientas de terceros como unxutils o cygwin, ya que este código está destinado a ejecutarse en una instalación de Windows con Python 2.6 con PyWin32 instalado)
Mira esta pregunta:
¿Qué usuario ejecutan los scripts Python como en Windows?
Al parecer, la respuesta es cambiar el archivo / carpeta para que no sea de solo lectura y luego eliminarlo.
Aquí está el controlador onerror()
de pathutils.py
mencionado por @Sridhar Ratnakumar en los comentarios:
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
Una solución simple es usar subprocess.call
from subprocess import call
call("rm -rf build/", shell=True)
Para ejecutar todo lo que quieras
Yo diría que implemente su propio rmtree con os.walk que garantice el acceso mediante el uso de os.chmod en cada archivo antes de intentar eliminarlo.
Algo como esto (no probado):
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)
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 se establece ignore_errors, los errores se ignoran; de lo contrario, si se establece onerror, se llama para manejar el error con argumentos (func, path, exc_info) donde func es os.listdir, os.remove u os.rmdir; ruta es el argumento para esa función que hizo que fallara; y exc_info es una tupla devuelta por sys.exc_info (). Si ignore_errors es falso y onerror es None, se genera una excepción. Ingrese aquí el código