检查文件是否在python中是符号链接


91

在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

Answers:


136

要确定目录条目是否为符号链接,请使用以下命令:

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

7
在Windows上,快捷方式显示为带有扩展名的文件lnk,并os.islink('a_shortcut.lnk')返回False
Evgeni Sergeev

1
@EvgeniSergeev这是因为它们只是文件-可能是Windows 9x以来唯一的文件系统是FAT / FAT32的宿醉。有关NTFS支持的所有类型的符号/硬链接和目录连接,请参见superuser.com/questions/347930/…。也就是说,我仍然不认为Python支持它们。
jmc

9
而且islink()不适用于Windows符号链接,即联结。因此,答案仅适用于Unix。
教父2015年

2
如果您需要Windows解决方案,请参考此stackoverflow.com/questions/27972776/…答案。
教父2015年

1
@TheGodfather:目录连接不是符号链接(IO_REPARSE_TAG_SYMLINK)。
jfs

11

对于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


此MAY只能找到有效的符号链接,而此MAY不能识别为符号链接但已损坏的文件。因此,如果您要过滤真实文件或所有符号链接(好的和坏的),则请确保进行其他检查
2114L3 2016年

@ 2114L3有效但已损坏的符号链接是什么意思?从带有断开符号链接的简单测试来看,这似乎is_symlink()是正确的,exists()也是错误的,这就是我所期望的。您能否提供您担心的消息来源?
乔纳森·H

1
@Sheljohn在我的评论exist()不属于答案之前,请检查该答案的编辑内容。使用存在是我的意思的另一项检查。因为单独使用is_symlink不足以达到原始版本的要求。
2114L3'4

在Windows上,这对我而言无法正常工作:is_symlink正在返回true不存在的文件(因此exists()也返回true)。
詹姆斯·希尔斯霍恩

3

不想膨胀这个话题,但是当我在寻找symlink来查找它们并将其转换为真实文件并在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")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.