【问题标题】:How do I unlock locked files and folders (mac) with Python如何使用 Python 解锁锁定的文件和文件夹(mac)
【发布时间】:2018-07-18 10:06:06
【问题描述】:

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

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

  1. 我将如何使用 Python 从每个文件/文件夹中删除锁定的属性(应该存在),然后如果文件以扩展名结尾,则删除该文件?
    最好这可以在下面的同一个函数中完成,因为遍历输入目录需要很长时间 - 只处理一次是要走的路。
  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))

【问题讨论】:

    标签: python python-3.x macos locked-files


    【解决方案1】:

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

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

    (有一个函数os.chflags,但是与锁定状态关联的标志不是常规的,而是os module documentation所说的“用户定义”标志,通过查看@987654326可以看到@.)

    为了解决您的问题,我会将上面的 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:
        ...
    

    【讨论】:

    • 我想您可能遇到了不同的异常?您在尝试删除文件时看到了什么异常?
    • 抛出异常"[Errno 66] Directory not empty: '/path/to/folder"(在最后一个if)我的测试目录仍然按照我上面提到的方式设置,锁定文件和同一级别的文件夹,以及锁定文件夹内的文件。作为递归,我希望文件夹中的文件解锁,认为文件夹为空(因为文件扩展名在列表中),因此删除文件夹,上升到起始目录并解锁然后删除另一个锁定的文件 -基本上什么都没有留下。然而,没有一个文件解锁,就好像什么都没发生一样。
    • 我认为您一定在某处遗漏了一些例外情况。你正在做的finally: return True 很奇怪:它基本上是说一个文件被删除了,而它没有被删除。它会抑制发生的任何异常。这使得调试非常困难!我建议摆脱它,事实上,摆脱除解锁之外的所有try:/except: 处理。这应该可以帮助您找到根本问题。
    • 刚刚添加了代码现在的样子。在锁定的图像上抛出 [Errno 1] Operation not permitted: /path/to/image.png 并中断。托管此目录的服务器位于 Windows 共享上这一事实与它有什么关系吗?我在这里迷路了,因为它可以从终端使用:chflags -R nouchg /PATH/TO/DIRECTORY/WITH/LOCKED/FILES/ 一次解锁。你能看看我做的编辑。如果所有其他方法都失败了,有没有办法将其转换为代码,以便在脚本的主要部分开始之前解锁所有内容,然后到它结束时,什么都看不到?
    • 您当然可以在开始时使用-R 进行此操作。就目前而言,听起来你得到的是IOError,而不是我得到的PermissionError?您可以尝试在except PermissionError: 部分中将PermissionError 替换为IOError
    猜你喜欢
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多