【问题标题】:Python: Check if a directory is an aliasPython:检查目录是否为别名
【发布时间】:2014-02-07 03:41:00
【问题描述】:

python 是否有一个简单的函数来检查一个目录是实际目录还是只是另一个目录的别名?我正在尝试列出目录中的所有文件/文件夹,但是由于这些别名文件夹,我丢失了一些看起来像这样的东西:

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/bundle/Home/捆绑/家庭/捆绑/家庭/捆绑/家庭/捆绑

我知道我可以编写一个函数来比较路径并退出,如果我看起来像是在绕圈子,但是有一个简单的函数可以完全做到我不知道的吗? 例如。 os.isAlias( …pathname… )

谢谢!

【问题讨论】:

    标签: macos python-2.7 directory-structure


    【解决方案1】:

    老问题,但我自己也遇到过。

    我没有完美的方法来检查文件是否是别名,但是,如果使用 mimetypes,python 将返回 None 以获得别名或符号链接。在某些情况下可能有用。我只在 macOS Big Sur 上的 python 3.8 中对此进行了测试。

    import mimetypes
    
    for idx, f in enumerate(filepaths):
        type = mimetypes.guess_type(f)[0]
        print(f"type is: {type}")
    

    返回(没有我添加的 cmets):

    type is: None # <-- Folder Alias
    type is: None # <-- File Alias
    type is: text/x-python
    type is: None # <-- Folder Alias
    type is: video/mp4
    type is: image/png
    type is: None # <-- Folder Alias
    type is: None # <-- Symlink
    type is: image/png
    type is: application/zip
    type is: image/png
    type is: image/jpeg
    type is: None # <-- Symlink
    

    我通过 exiftool 运行了一些文件,只是为了查看它们返回的类型,别名和符号链接都显示如下:

    File Type                       : ALIAS
    File Type Extension             : alias
    MIME Type                       : application/x-macos
    

    您可能能够为这些初始化 mimetypes,但尚未测试并且不确定如果其他任何内容显示为 application/x-macos 是否会给出误报

    【讨论】:

      【解决方案2】:

      您可以在 Mac OS X 中使用 GetFileInfo 命令检查文件或目录是否为别名。如果 foo 是别名,GetFileInfo -aa foo 将打印一行“1”,如果不是,则打印“0”。

      import subprocess
      
      def is_alias(path):
          return subprocess.check_output(["GetFileInfo", "-aa", path]) == "1\n"
      

      每次检查都生成一个进程似乎有点难过,但我认为这适用于 Mac OS X 的版本,可能是 10.4.4 (2006)、32 位、64 位、Python 2 和 Python 3。我拥有的 GetFileInfo 版本(从 2009 年开始)是“通用”i386 + PPC 二进制文件。

      GetFileInfo 是 Xcode 的一部分,它很大,但您可以单独下载命令行工具(参见“单独下载”部分 here)。

      https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/GetFileInfo.1.html

      【讨论】:

        【解决方案3】:

        这是os.path.realpath 的一个版本,它适用于 Mac 别名以及符号链接在 Python 2 下

        from Carbon import File
        def osx_realpath (path):
            return File.FSResolveAliasFile(path, True)[0].as_pathname()
        

        如果你在递归到每个目录之前调用 osx_realpath,你应该避免重复。或者,您可以定义类似

        def is_osx_realpath (path):
            return path == osx_realpath(path)
        

        但是,在这里您必须稍微担心误报。如果您过滤 is_osx_realpath 并且您开始的路径是别名,您的程序将停止而不查看任何内容。

        到目前为止,我不知道如何在 Python 3 下执行此操作。我有一个问题 here 我希望得到答案。现在我不能比使用subprocess.callinvoke something that does the check on the command line 做得更好。

        编辑:我应该补充一点,Carbon.File 不仅在 Python 3 中不可用,而且已被弃用,因此最好在 Python 2 中避免使用——但它是我所知道的 Python 2 中最实用的解决方案现在。

        编辑 2:这是一种检查文件是否是我认为对 Python 3 友好的别名的方法。但是,我没有解析别名的代码。我相信你需要安装 PyObjC。

        from AppKit import NSWorkspace
        def is_alias (path):
            uti, err = NSWorkspace.sharedWorkspace().typeOfFile_error_(
                os.path.realpath(path), None)
            if err:
                raise Exception(unicode(err))
            else:
                return "com.apple.alias-file" == uti
        

        (source)

        【讨论】:

        • 这为别名返回 false(耶!),但为符号链接返回错误:File.FSResolveAliasFile(path, True)[0].as_pathname() MacOS.Error: (-120, 'Directory not found')。现在,我几乎求助于子进程调用。具体来说,command = ["mdfind", "kMDItemKind == 'Alias'"]subprocess.call(command) 将打印出所有 Alias 文件,我猜这些文件与您正在做的类似......? (如果不是并且你不知道我在说什么,mdfind == 聚光灯查找和mdls 大致类似于ls)。
        • 上帝,对于可怕的格式感到抱歉。双空间对我来说不是新的东西。另外,我会赞成您的回答,但我没有足够的票来赞成(!):-/
        • 不确定是否可以将换行符放入 cmets。我确认上面的代码适用于我机器上的符号链接。您是否尝试过致电os.path.exists 以确保您正在查询的链接确实存在?无论如何,您都可以捕获异常或先检查os.path.islink
        • os.path.exists 为别名返回 true,为符号链接返回 falseos.path.islink 为别名返回 false,为符号链接返回 _true。我认为这会解决它,因为我可以编写一个 if-else 语句来捕获任何一种情况。唉,.app 可执行文件对于 os.path.islinkos.path.exists 都返回 false(对于 os.path.isdiros.path.isfile 也是 false!)。由于我仍在 Python 3 中,因此我尚未尝试过您的上述 Edit2 方法,但无论如何我已经接受了您的答案,因为它看起来是迄今为止最接近解决方案的方法。感谢所有的帮助! :)
        • “因为我还在 Python 3 中”。抱歉,我的意思是 Python 2.7。
        【解决方案4】:

        上面的答案是错误的。 虽然 Finder 确实将符号链接报告为别名,但它们是不同的东西。

        符号链接是 UNIX 的基本功能,但别名是 Apple 独有的功能。 如果您对此表示怀疑,请创建指向目录和别名的符号链接。符号链接通常很小,通常为 50-100 字节,而别名可能为几 MB。

        os.path.islink( … ) 将报告符号链接,但不报告别名。

        我不确定您如何在 Python 中找到它们,但以下链接显示了其他方法。

        https://stackoverflow.com/a/21151368/838253

        【讨论】:

        • 你是对的!显然,相同的符号用于 Mac 上的别名和符号链接,而我在上面发布的 Home/bundle 路径实际上是符号链接而不是别名,这就是 os.path.islink( … ) 为我工作的原因。感谢您的链接。今晚晚些时候我会更详细地讨论它,看看它是否能找到答案。
        • (呃,抱歉。我无法投票赞成你的答案!它说我需要至少 15 次重复!)
        • 所以任何人都知道别名到底是什么,它的用途是什么?
        猜你喜欢
        • 2020-07-19
        • 1970-01-01
        • 2014-08-04
        • 2015-01-09
        • 1970-01-01
        • 1970-01-01
        • 2016-01-25
        • 2012-07-21
        • 2018-12-23
        相关资源
        最近更新 更多