Как удалить доступный только для чтения attrib каталог с Python в Windows? - PullRequest
38 голосов
/ 28 января 2011

У меня есть каталог только для чтения, скопированный из каталога с управлением версиями, который заблокирован.enter image description here

Когда я попытался удалить этот каталог с помощью команды shutil.rmtree(TEST_OBJECTS_DIR), я получил следующее сообщение об ошибке:

WindowsError: [Error 5] Access is denied: 'C:\...\environment.txt'
  • В: Как я могу изменить атрибутвсе в целом структуре каталогов?

Ответы [ 5 ]

50 голосов
/ 28 января 2011

Если вы используете shutil.rmtree, вы можете использовать член onerror этой функции, чтобы предоставить функцию, которая принимает три параметра: function, path и info исключений. Вы можете использовать этот метод, чтобы пометить файлы только для чтения как доступные для записи при удалении дерева.

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 )

Теперь, если честно, функцию ошибки можно вызывать по разным причинам. Параметр 'func' может сказать вам, какая функция "провалилась" (os.rmdir () или os.remove ()). То, что вы здесь делаете, зависит от того, насколько пуленепробиваемым вы хотите, чтобы ваше дерево было. Если вам действительно нужно пометить файлы как доступные для записи, вы можете сделать то, что я делал выше. Если вы хотите быть более осторожным (т. Е. Определить, не удалось ли удалить каталог, или если при попытке удалить файл произошло нарушение общего доступа к файлу), необходимо вставить соответствующую логику в функцию on_rm_error () .

10 голосов
/ 28 января 2011

Не тестировалось, но было бы, что-то вроде включения доступа на запись.

import os, stat

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

Возможно, вам потребуется объединить с os.walk, чтобы включить все записи.что-то вроде

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)
5 голосов
/ 30 ноября 2011

Метод, который я использовал, это сделать:

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

Прежде, чем кто-то прыгнет на меня, я знаю, что это ужасно непитонично, но, возможно, оно проще, чем более традиционные ответы, приведенные выше, и надежно.

Я не уверен, что происходит с атрибутами чтения / записи в каталогах. Но это еще не проблема.

4 голосов
/ 20 декабря 2013

Принятый ответ почти верен, но может произойти сбой в случае подкаталога только для чтения.

Функция передается в качестве аргумента обработчику rmtree onerror.

Я бы предложил:

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)

В случае повторного сбоя функции вы можете увидеть причину и продолжить удаление.

4 голосов
/ 19 февраля 2013
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)

копия из: http://code.activestate.com/recipes/303343-changing-file-attributes-on-windows/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...