Перевірте, чи файл є символьним посиланням у 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

Відповіді:


136

Щоб визначити, чи запис каталогу є символічним посиланням, використовуйте це:

os.path.islink (шлях)

Повернути True, якщо шлях посилається на запис каталогу, який є символічним посиланням. Завжди неправда, якщо символічні посилання не підтримуються.

Наприклад, враховуючи:

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.
Євген Сергєєв

1
@EvgeniSergeev Це тому, що це лише файли - можливо, похмілля від Windows 9x днів, коли єдиною файловою системою була FAT / FAT32. Ознайомтесь із цим superuser.com/questions/347930/… про всі типи символічних / жорстких посилань та стиків каталогів, що підтримуються на NTFS. Тим не менш, я все ще не думаю, що Python їх підтримує.
jmc

9
І islink () не працює для символьних посилань Windows, тобто перехрестя. Тож відповідь застосовується лише для Unix.
Хрещений батько

2
Зверніться до цієї відповіді stackoverflow.com/questions/27972776/…, якщо вам потрібне рішення Windows.
Хрещений батько

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


це МОЖЕ знайти лише дійсне символічне посилання, це МОЖЕ не визначити файл, який є символічним посиланням, але порушений. тож якщо ви фільтруєте реальні файли чи всі символічні посилання (хороші та погані), то переконайтеся, що ви зробите додаткові перевірки
2114L3

@ 2114L3 Що означає дійсне, але зламане символічне посилання? З простого тестування з непрацюючим символічним посиланням здається, що is_symlink()це правда, і exists()це помилка, саме цього я і очікував. Чи можете ви дати джерело для своїх проблем?
Джонатан Х

1
@Sheljohn перевіряє редагування цієї відповіді, перш ніж мій коментар існує () не був частиною відповіді. використання існує - це додаткова перевірка, яку я мав на увазі. оскільки використання оригіналу is_symlink недостатньо відповідно до оригінальної версії.
2114L3,

У 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")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.