shutil.rmtreeは、「アクセスが拒否された」[複製]でWindowsで失敗します
-
27-09-2019 - |
質問
この質問にはすでに答えがあります:
- Pythonでディレクトリを削除します 6回の回答
Pythonで、実行時 shutil.rmtree
読み取り専用ファイルを含むフォルダーを介して、次の例外が印刷されています。
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'
ファイルプロパティを見るダイアログ私はそれに気付きました af.msg
ファイルは読み取り専用に設定されています。
質問は次のとおりです 最も簡単です この問題を回避するための回避策/修正 - 私の意図が同等のことをすることであることを考えると rm -rf build/
しかし、Windowsで? (UnxutilsやCygwinなどのサードパーティツールを使用することなく - このコードは、Pywin32をインストールしたPython 2.6を使用して裸のWindowsインストールで実行されることを目標としています)
解決
この質問をチェックしてください:
WindowsのようにPythonスクリプトはどのユーザーを実行しますか?
どうやら答えは、ファイル/フォルダーを読み取り専用に変更してから削除するように変更することです。
これがそうです onerror()
からのハンドラー pathutils.py
@sridhar ratnakumarがコメントで言及しました:
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
他のヒント
私はあなた自身のrmtreeを実装すると思います os.walk これにより、使用してアクセスが保証されます os.chmod 削除しようとする前に各ファイルに。
このようなもの(テストされていない):
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)
まあ、マークされたソリューションは私のためには機能しませんでした...代わりにこれをしました:
os.system('rmdir /S /Q "{}"'.format(directory))
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
INGRORE_ERRORSが設定されている場合、エラーは無視されます。それ以外の場合、Onerrorが設定されている場合、funcがos.listdir、os.remove、またはos.rmdirである引数(func、path、exc_info)でエラーを処理するように呼び出されます。パスは、それを失敗させたその関数に対する議論です。 exc_infoはsys.exc_info()によって返されたタプルです。 Ingrore_Errorsがfalseで、Onerrorが存在しない場合、例外が提起されます。
簡単な回避策が使用されています subprocess.call
from subprocess import call
call("rm -rf build/", shell=True)
あなたが望むすべてを実行するために。