2010-04-16 15 views
49

अजगर में, 'प्रवेश निषेध है' जब कि केवल पढ़ने के लिए फ़ाइल है किसी फ़ोल्डर के ऊपर shutil.rmtree चल रहा है, निम्न अपवाद छपा है: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 की तरह तीसरे पक्ष के उपकरणों का उपयोग किए बिना के रूप में इस कोड को एक नंगे विंडोज पर चलने के लिए लक्षित है अजगर 2.6 के साथ स्थापित w/PyWin32 स्थापित)

+4

'shutil.rmtree' फ़ाइलों को हटाने के लिए' os.remove' का उपयोग करता है। 'os.remove' केवल पढ़ने योग्य फ़ाइलों को ठीक करता है (कम से कम यूनिक्स पर)। यदि osremove' उपयोग में है, तो विंडोज़ पर फ़ाइल को हटा नहीं सकता है। – jfs

+0

[पाइथन में निर्देशिका को हटाने] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/1889597/deleting-directory-in-python) – mozzbozz

उत्तर

63

की जांच:

What user do python scripts run as in windows?

स्पष्ट रूप से उत्तर फ़ाइल/फ़ोल्डर को केवल पढ़ने के लिए बदलने के लिए नहीं है और फिर इसे हटा दें।

यहाँ pathutils.py से onerror() हैंडलर टिप्पणी में @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

हे। मैंने अभी http://www.voidspace.org.uk/downloads/pathutils.py –

+0

पर 'आतंकवादी' हैंडलर की खोज की .. पता चला कि http://trac.pythonpaste.org/pythonpaste/ticket/359 –

+1

के बावजूद इस उत्तर स्थिति के लिए टिप्पणियां 'फ़ाइल/फ़ोल्डर को केवल पढ़ने के लिए नहीं बदलें', मुझे अभी भी केवल-पढ़ने वाले फ़ोल्डर्स पर पहुंच से वंचित कर दिया गया है। [यह] (http://stackoverflow.com/a/1889686/116047) कार्यान्वयन, हालांकि काम किया। – Pakman

17

मैं कहना चाहता हूँ कि यह os.walk हटाने का प्रयास करने से पहले प्रत्येक फ़ाइल पर os.chmod का उपयोग करके पहुँच सुनिश्चित करता है के साथ अपने स्वयं rmtree लागू।

कुछ इस तरह (untested):

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

यह लगभग सही है - विंडोज केवल 'stat.S_IWRITE' का समर्थन करता है (जो वही है जो आप चाहते हैं) - http: // docs। python.org/library/os.html#os.chmod –

+0

मैंने परीक्षण किया कि 'os.chmod (फ़ाइल नाम, stat.S_IWUSR)' केवल पढ़ने के लिए ध्वज हटा दिया गया है, इसलिए यह WinXP पर काम करता है। और इस पर विचार करते हुए दस्तावेज़ 'stat._IWRITE'' के बारे में क्या कहते हैं: "S_IWUSR के लिए यूनिक्स वी 7 समानार्थी" (http://docs.python.org/library/stat.html#stat.S_IWRITE), मैं अपना कोड सोच रहा हूं वैसे भी ठीक है। – Epcylon

+0

ग्रेट, फाइल पथ के साथ जो बहुत लंबा है, यह एकमात्र तरीका जैसा लगता है। शायद shutil.rmtree को प्रतिबद्ध करने या बदलने की सिफारिश। – Anthony

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, पथ, 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) 

उपयोग कर रहा है सब कुछ आप चाहते हैं पर अमल करने में है।