¿Cómo verificar si el archivo es un enlace simbólico en Python?

5 minutos de lectura

avatar de usuario
bandicoot

En Python, ¿hay una función para verificar si un archivo/directorio dado es un enlace simbólico? Por ejemplo, para los archivos a continuación, mi función contenedora debería devolver 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

avatar de usuario
levon

Para determinar si una entrada de directorio es un enlace simbólico, use esto:

os.ruta.islink(ruta)

Retorna True si ruta hace referencia a una entrada de directorio que es un enlace simbólico. Siempre falso si los enlaces simbólicos no son compatibles.

Por ejemplo, dado:

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

  • En Windows, Atajos aparecen como archivos con extensión lnky os.islink('a_shortcut.lnk') devoluciones False.

    –Evgeni Sergeev

    16 de octubre de 2013 a las 9:42

  • @EvgeniSergeev Eso se debe a que son solo archivos, posiblemente una resaca de los días de Windows 9x cuando el único sistema de archivos era FAT/FAT32. Mira esto superusuario.com/questions/347930/… para todos los tipos de enlaces simbólicos/fijos y uniones de directorio compatibles con NTFS. Dicho esto, todavía no creo que Python los admita.

    – jmc

    6 de noviembre de 2013 a las 21:56

  • Y islink() no funciona para enlaces simbólicos de Windows, es decir, uniones. Entonces la respuesta es aplicable solo para Unix.

    – El Padrino

    2 de marzo de 2015 a las 9:14

  • Consulte esta respuesta stackoverflow.com/questions/27972776/… si necesita una solución de Windows.

    – El Padrino

    21 de mayo de 2015 a las 10:58

  • @TheGodfather: la unión de directorios no es un enlace simbólico (IO_REPARSE_TAG_SYMLINK).

    – jfs

    4 de noviembre de 2016 a las 10:08

avatar de usuario
kemin zhou

Para python 3.4 y versiones posteriores, puede usar la clase Path

from pathlib import Path


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

Debe tener cuidado al usar el método is_symlink(). Devolverá True incluso si el destino del enlace no existe siempre que el objeto nombrado sea un enlace simbólico. Por ejemplo (Linux/Unix):

ln -s ../nonexistentfile flnk

Luego, en su directorio actual, inicie python

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

El programador tiene que decidir lo que realmente quiere. Python 3 parece haber cambiado el nombre de muchas clases. Puede valer la pena leer la página del manual para la clase Path: https://docs.python.org/3/library/pathlib.html

  • esto PUEDE solo encontrar un enlace simbólico válido, esto PUEDE no identificar un archivo que es un enlace simbólico pero está roto. por lo tanto, si está filtrando archivos reales o todos los enlaces simbólicos (buenos y malos), asegúrese de realizar verificaciones adicionales

    – 2114L3

    25/09/2016 a las 12:31

  • @2114L3 ¿Qué significa un enlace simbólico válido pero roto? A partir de una simple prueba con un enlace simbólico roto, parece que is_symlink() es cierto, y exists() es falso, que es lo que yo esperaría. ¿Puede dar una fuente para sus preocupaciones?

    – Jonathan H.

    5 de marzo de 2018 a las 2:07


  • @Sheljohn verifique las ediciones en esta respuesta, antes de que exista mi comentario () no era parte de la respuesta. usar existe es un control adicional de lo que quise decir. ya que usar is_symlink solo no es suficiente según la versión original.

    – 2114L3

    2 de abril de 2018 a las 0:56


  • En Windows esto no funciona correctamente para mí: is_symlink esta regresando true para archivos inexistentes (entonces exists() también regresa true).

    –James Hirschorn

    19 de agosto de 2019 a las 17:01

avatar de usuario
usuario1767754

Sin la intención de inflar este tema, pero fui redirigido a esta página mientras buscaba enlaces simbólicos para encontrarlos y convertirlos en archivos reales y encontré este script dentro de la biblioteca de herramientas de 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")

  • ¿Puedes explicar lo que está pasando aquí? Se ve un poco extraño, ya que parece que está eliminando (desvinculando) el archivo antes de en realidad escribirlo de nuevo. ¿Cómo puede ser esto? También el último mkrealfile(...) está al mismo nivel que su propia función…

    – no2qubit

    18 oct 2020 a las 19:48


  • Parece estar abriendo (f_in) el archivo al que apunta el enlace simbólico, eliminando el enlace simbólico (pero el archivo apuntado todavía se está leyendo), luego en la ubicación donde estaba el enlace simbólico (f_out), escribiendo / copiando el archivo . Mirando el enlace, el código src en cuestión se ha actualizado con el with-as modismo y usa lectura/escritura binaria (mejor para copiar archivos), de lo contrario lo mismo.

    – JWCS

    1 de febrero a las 16:37

¿Ha sido útil esta solución?