2012-06-17 64 views
60

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

# 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 
+6

实际上,将该问题复制并粘贴到Google中现在会产生此问题。 – porgarmingduod

回答

96

要确定某个目录项是符号链接,使用这样的:

os.path.islink(path)

返回真,如果路径指向一个目录条目是一个符号 链接。如果不支持符号链接,则始终为假。

例如,给定:

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 
+4

在Windows上,_Shortcuts_显示为扩展名为'lnk'的文件,'os.islink('a_shortcut.lnk')'返回False。 –

+1

@EvgeniSergeev这是因为它们只是文件 - 可能是Windows 9x时代的唯一文件系统是FAT/FAT32的宿醉。请参阅http://superuser.com/questions/347930/what-are-the-various-link-types-in-windows-how-do-i-create-them了解所有类型的符号/硬链接和目录在NTFS上支持的路口。也就是说,我仍然认为Python不支持它们。 – jmc

+7

islink()不适用于Windows符号链接,即联结。所以答案只适用于Unix。 –

5

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

然后,在当前目录火起来蟒蛇

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

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

+0

这可能只会找到有效的符号链接,这可能不会识别符号链接但被破坏的文件。所以如果你正在过滤真正的文件或所有符号链接(好的和坏的),那么确保你做了额外的检查 – 2114L3

+0

@ 2114L3什么是一个有效但破碎的符号链接是什么意思?从一个破损的符号链接的简单测试看来,'is_symlink()'为真,'exists()'为假,这正是我所期望的。你能否提供你的疑虑来源? – Sheljohn

1

而无意臃肿这个话题,但我被重定向到这个页面,因为我一直在寻找的符号链接的找到他们并将其转换为真正的文件和在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") 
相关问题