2012-06-17 16 views
60

En python, ¿hay alguna función para verificar si un archivo/directorio determinado es un enlace simbólico? Por ejemplo, para los archivos a continuación, mi función contenedora debería devolver True.Comprobar si el archivo es un enlace simbólico en 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

En realidad, copiar y pegar esa pregunta en google ahora genera esta pregunta. – porgarmingduod

Respuesta

96

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

os.path.islink(path)

devueltos TRUE si la ruta se refiere a una entrada de directorio que es un enlace simbólico. Siempre falso si los enlaces simbólicos no son compatibles.

Por ejemplo, dada:

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

En Windows, _Shortcuts_ aparecen como archivos con la extensión 'lnk', y' os.islink ('a_shortcut.lnk') 'devuelve' False'. –

+1

@EvgeniSergeev Eso es porque solo son archivos, posiblemente una resaca de Windows 9x días cuando el único sistema de archivos era FAT/FAT32. Consulte este http://superuser.com/questions/347930/what-are-the- various-link-types-in-windows-how-do-i-create-them para todos los tipos de enlaces y directorios simbólicos/duros. uniones soportadas en NTFS. Dicho eso, todavía no creo que Python los apoye. – jmc

+7

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

5

para Python 3.4 y arriba, puede utilizar la clase Path

from pathlib import Path 


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

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

ln -s ../nonexistentfile flnk 

A continuación, en el directorio actual el fuego de pitón

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

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

+0

este MAY solo encuentra un enlace simbólico válido, esto PUEDE no identificar un archivo que es un enlace simbólico pero está roto. así que si está filtrando archivos reales o todos los enlaces simbólicos (buenos y malos), asegúrese de hacer comprobaciones adicionales – 2114L3

+0

@ 2114L3 ¿Qué significa un enlace simbólico válido pero roto? A partir de pruebas simples con un enlace simbólico roto, parece que 'is_symlink()' es verdadero, y 'exists()' es falso, que es lo que yo esperaría. ¿Puedes dar una fuente para tus preocupaciones? – Sheljohn

1

Sin la intención de inflar este tema, pero me redireccionaron a esta página porque estaba buscando enlaces simbólicos para encontrarlos y convertirlos a archivos reales y encontré esta secuencia de comandos 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") 
Cuestiones relacionadas