Как разблокировать заблокированные файлы и папки (Mac) с помощью Python

В качестве "очистки" после завершения основной цели моего сценария вызывается функция для рекурсивного просмотра каждой папки и удаления всех файлов, которые заканчиваются предварительно определенным набором расширений.

Я во время тестирования обнаружил, что некоторые файлы с расширением в списке для удаления на самом деле выдают ошибку: [Errno 1] Operation not permitted: '/location/of/locked/file.png, Глядя на сам файл, он кажется заблокированным (на Mac).

  1. Как мне удалить удаленный атрибут (если он существует) из каждого файла / папки с помощью Python, а затем удалить файл, если он заканчивается расширением?
    Желательно, чтобы все это можно было выполнить с помощью одной и той же функции, представленной ниже, так как для обхода входного каталога требуется много времени - обработка каждого из них - только один раз.
  2. Как это влияет на целостность скрипта в Windows?
    Я позаботился о его программировании таким образом, чтобы он был совместим между операционными системами, но (насколько мне известно) заблокированный атрибут не существует в Windows, как в Mac, и может вызывать неизвестные побочные эффекты.

REMOVE_FILETYPES = ('.png', '.jpg', '.jpeg', '.pdf')

def cleaner(currentPath):
  if not os.path.isdir(currentPath):
    if currentPath.endswith(REMOVE_FILETYPES) or os.path.basename(currentPath).startswith('.'):
      try:
        os.remove(currentPath)
        print('REMOVED: \"{removed}\"'.format(removed = currentPath))
      except BaseException as e:
        print('ERROR: Could not remove: \"{failed}\"'.format(failed = str(e)))
      finally:
        return True
    return False

  if all([cleaner(os.path.join(currentPath, file)) for file in os.listdir(currentPath)]):
    try:
      os.rmdir(currentPath)
      print('REMOVED: \"{removed}\"'.format(removed = currentPath))
    except:
      print('ERROR: Could not remove: \"{failed}\"'.format(failed = currentPath))
    finally:
      return True
  return False

cleaner(r'/path/to/parent/dir')

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


РЕДАКТИРОВАТЬ: Удалена обработка ошибок в соответствии с запросом

def cleaner(currentPath):
if sys.platform == 'darwin':
    os.system('chflags nouchg {}'.format(currentPath))
if not os.path.isdir(currentPath):
    if currentPath.endswith(REMOVE_FILETYPES) or os.path.basename(currentPath).startswith('.'):
        try:
            os.remove(currentPath)
            print('REMOVED: \"{removed}\"'.format(removed=currentPath))
        except PermissionError:
            if sys.platform == 'darwin':
                os.system('chflags nouchg {}'.format(currentPath))
                os.remove(currentPath)
if all([cleaner(os.path.join(currentPath, file)) for file in os.listdir(currentPath)]) and not currentPath == SOURCE_DIR:
    os.rmdir(currentPath)
    print('REMOVED: \"{removed}\"'.format(removed=currentPath))

1 ответ

Вы можете разблокировать файл с помощью chflags команда:

os.system('chflags nouchg {}'.format(filename))

(Есть функция os.chflags, но флаг, связанный с заблокированным статусом, является не обычным, а каким os Документация модуля вызывает "определяемый пользователем" флаг, как вы можете видеть, посмотрев на os.stat(locked_filename).st_flags.)

Чтобы решить вашу проблему, я бы добавил chflags Команда выше для конкретного except: в случае ошибки вы пытаетесь удалить заблокированный файл вместе с проверкой платформы:

try:
    os.remove(currentPath)
    print('REMOVED: \"{removed}\"'.format(removed = currentPath))
except PermissionError:
    if sys.platform == 'darwin':
        os.system('chflags nouchg {}'.format(currentPath))
        os.remove(currentPath)
    else:
        raise
except BaseException as e:
    ...
Другие вопросы по тегам