2010-04-16 157 views
49

在Python中,包含只讀文件的文件夾在運行時shutil.rmtree,以下異常印:shutil.rmtree在Windows上失敗,「訪問被拒絕」

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的 - 因爲這代碼是針對要在裸露的Windows上運行的Python 2.6安裝瓦特/安裝PyWin32)

+4

'shutil.rmtree'使用'os.remove'來刪除文件。 'os.remove'刪除只讀文件就好了(至少在Unix上)。如果正在使用,「os.remove」無法刪除Windows上的文件。 – jfs 2010-04-16 22:24:04

+0

[在Python中刪除目錄]可能的重複(http://stackoverflow.com/questions/1889597/deleting-directory-in-python) – mozzbozz 2015-01-21 16:20:58

回答

63

檢查這個問題了:

What user do python scripts run as in windows?

顯然,答案是將文件/文件夾更改爲不可讀取,然後將其刪除。

下面是pathutils.pyonerror()處理器通過@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 
+1

heh。我剛剛在http://www.voidspace.org.uk/downloads/pathutils.py – 2010-04-16 22:27:33

+0

發現了'onerror'處理程序..發現通過http://trac.pythonpaste.org/pythonpaste/ticket/359 – 2010-04-16 22:33:57

+1

即使此答案狀態的評論'將文件/文件夾更改爲不可讀',但我仍然收到只讀文件夾上的拒絕訪問權限。儘管如此,[這](http://stackoverflow.com/a/1889686/116047)實現工作。 – Pakman 2013-11-13 17:50:36

17

我會說有os.walk確保試圖刪除它之前對每個文件使用os.chmod訪問實現自己的rmtree。

像這樣(未經):

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

這幾乎是正確的 - Windows只支持'stat.S_IWRITE'(這正是你想要的) - http:// docs。 python.org/library/os.html#os.chmod – 2010-04-16 22:25:26

+0

我測試了'os.chmod(filename,stat.S_IWUSR)'去掉了只讀標誌,所以它在WinXP上工作。考慮到這是文檔關於'stat.S_IWRITE'的說法:「S_IWUSR的Unix V7同義詞」(http://docs.python.org/library/stat.html#stat.S_IWRITE),我在想我的代碼反正是對的。 – Epcylon 2010-04-17 13:27:33

+0

太棒了,文件路徑太長,這似乎是唯一的方法。也許建議承諾或改變shutil.rmtree。 – Anthony 2015-04-10 00:03:16

5

好了,明顯的解決方案並沒有爲我工作...這樣做,而不是:

os.system('rmdir /S /Q "{}"'.format(directory)) 
0
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 

如果ignore_errors是設置,錯誤被忽略;否則,如果設置了錯誤 ,則調用它來處理帶有參數(func, path,exc_info)的錯誤,其中func是os.listdir,os.remove或os.rmdir; 路徑是導致它失敗的那個函數的參數;和 exc_info是由sys.exc_info()返回的元組。如果ignore_errors 是假的,是的onerror無,一個例外是這裏

1

raised.enter代碼簡單的解決方法是使用subprocess.call

from subprocess import call 
call("rm -rf build/", shell=True) 

爲了執行你想要的一切。