【问题标题】:How to check if file is a symlink in Python?如何检查文件是否是Python中的符号链接?
【发布时间】:2012-06-19 13:42:25
【问题描述】:

在 Python 中,是否有检查给定文件/目录是否为符号链接的函数?例如,对于以下文件,我的包装函数应返回 True

# ls -l
total 0
lrwxrwxrwx 1 root root 8 2012-06-16 18:58 dir -> ../temp/
lrwxrwxrwx 1 root root 6 2012-06-16 18:55 link -> ../log

【问题讨论】:

    标签: python operating-system


    【解决方案1】:

    要确定目录条目是否是符号链接,请使用:

    os.path.islink(path)

    如果路径引用了一个符号目录条目,则返回 True 关联。如果不支持符号链接,则始终为 False。

    例如,给定:

    drwxr-xr-x   2 root root  4096 2011-11-10 08:14 bin/
    drwxrwxrwx   1 root root    57 2011-07-10 05:11 initrd.img -> boot/initrd.img-2..
    
    >>> import os.path
    >>> os.path.islink('initrd.img')
    True
    >>> os.path.islink('bin')
    False
    

    【讨论】:

    • 在 Windows 上,快捷方式显示为扩展名为 lnk 的文件,os.islink('a_shortcut.lnk') 返回 False
    • @EvgeniSergeev 那是因为它们只是文件——可能是 Windows 9x 天的遗留物,当时唯一的文件系统是 FAT/FAT32。有关 NTFS 支持的所有类型的符号/硬链接和目录连接,请参阅此 superuser.com/questions/347930/…。也就是说,我仍然认为 Python 不支持它们。
    • 而且 islink() 不适用于 Windows 符号链接,即联结。所以答案只适用于 Unix。
    • 如果您需要 Windows 解决方案,请参考这个stackoverflow.com/questions/27972776/… 答案。
    • @TheGodfather:目录连接不是符号链接 (IO_REPARSE_TAG_SYMLINK)。
    【解决方案2】:

    对于 python 3.4 及更高版本,您可以使用 Path 类

    from pathlib import Path
    
    
    # rpd is a symbolic link
    >>> Path('rdp').is_symlink()
    True
    >>> Path('README').is_symlink()
    False
    

    使用 is_symlink() 方法时必须小心。只要命名对象是符号链接,即使链接的目标不存在,它也会返回 True。例如(Linux/Unix):

    ln -s ../nonexistentfile flnk
    

    然后,在你的当前目录中启动 python

    >>> from pathlib import Path
    >>> Path('flnk').is_symlink()
    True
    >>> Path('flnk').exists()
    False
    

    程序员必须决定他/她真正想要什么。 Python 3 似乎重命名了很多类。可能值得阅读 Path 类的手册页:https://docs.python.org/3/library/pathlib.html

    【讨论】:

    • 这可能只找到有效的符号链接,这可能无法识别一个符号链接但已损坏的文件。因此,如果您要过滤真实文件或所有符号链接(好的和坏的),请确保进行额外检查
    • @2114L3 有效但损坏的符号链接是什么意思?从符号链接损坏的简单测试来看,is_symlink() 似乎是真的,exists() 是假的,这正是我所期望的。您能否提供您的担忧的来源?
    • @Sheljohn 检查对此答案的编辑,在我的评论存在之前()不是答案的一部分。使用存在是我的意思的额外检查。因为按照原始版本单独使用 is_symlink 是不够的。
    • 在 Windows 上,这对我来说不能正常工作:is_symlink 正在为不存在的文件返回 true(所以 exists() 也返回 true)。
    【解决方案3】:

    无意膨胀这个话题,但我被重定向到这个页面,因为我正在寻找符号链接来找到它们并将它们转换为真实文件,并在 python 工具库中找到了这个脚本。

    #Source https://github.com/python/cpython/blob/master/Tools/scripts/mkreal.py
    
    
    import sys
    import os
    from stat import *
    
    BUFSIZE = 32*1024
    
    def mkrealfile(name):
        st = os.stat(name) # Get the mode
        mode = S_IMODE(st[ST_MODE])
        linkto = os.readlink(name) # Make sure again it's a symlink
        f_in = open(name, 'r') # This ensures it's a file
        os.unlink(name)
        f_out = open(name, 'w')
        while 1:
            buf = f_in.read(BUFSIZE)
            if not buf: break
            f_out.write(buf)
        del f_out # Flush data to disk before changing mode
        os.chmod(name, mode)
    
        mkrealfile("/Users/test/mysymlink")
    

    【讨论】:

    • 你能解释一下这里发生了什么吗?看起来有点奇怪,因为您似乎在 实际写回文件之前删除(取消链接)文件。怎么会这样?最后一个mkrealfile(...) 也与它自己的函数处于同一级别...
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 2012-02-28
    • 2023-04-03
    • 2014-05-18
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多