如何使用 Python 解锁锁定的文件和文件夹 (mac)

How do I unlock locked files and folders (mac) with Python

作为脚本的主要目的完成后的“清理”,将调用一个函数来递归查看每个文件夹并删除所有以一组预先确定的扩展名结尾的文件。

我在测试过程中发现,要删除的文件列表中的某些文件扩展名实际上会引发错误:[Errno 1] Operation not permitted: '/location/of/locked/file.png。查看文件本身,它似乎是 Locked(在 mac)。

  1. 我如何使用 Python 从每个 file/folder 中删除锁定属性(如果存在),然后删除以扩展名结尾的文件?
    最好这一切都可以在下面的同一个函数中完成,因为遍历输入目录需要很长时间 - 每个只处理一次是可行的方法。
  2. 这对 Windows 上的脚本完整性有何影响?
    我已经以使其在操作系统之间兼容的方式对其进行编程,但是(据我所知) locked 属性在 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))

您可以使用chflags命令解锁文件:

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

(有一个函数os.chflags,但是与锁定状态关联的标志不是常规标志,而是os module documentation所谓的"user-defined"标志,你可以查看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:
    ...