Python'da dosyanın symlink olup olmadığını kontrol edin


98

Python'da, belirli bir dosyanın / dizinin bir sembolik bağlantı olup olmadığını kontrol eden bir işlev var mı? Örneğin, aşağıdaki dosyalar için sarmalayıcı işlevim dönmelidir 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

Yanıtlar:


143

Bir dizin girişinin bir sembolik bağlantı olup olmadığını belirlemek için şunu kullanın:

os.path.islink (yol)

Yol, sembolik bir bağlantı olan bir dizin girdisine başvuruyorsa True döndür. Sembolik bağlantılar desteklenmiyorsa Her Zaman Yanlış.

Örneğin, verilen:

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

8
Windows'ta Kısayollar , uzantılı dosyalar olarak görünür lnkve os.islink('a_shortcut.lnk')geri döner False.
Evgeni Sergeev

1
@EvgeniSergeev Bunun nedeni sadece dosya olmalarıdır - muhtemelen tek dosya sisteminin FAT / FAT32 olduğu Windows 9x günlerinden kalma bir akşamdan kalma. NTFS'de desteklenen tüm sembolik / sabit bağlantı ve dizin bağlantı türleri için bu superuser.com/questions/347930/… adresine bakın . Bununla birlikte, hala Python'un onları desteklediğini düşünmüyorum.
jmc

10
Ve islink () Windows sembolik bağlar, yani kavşaklar için çalışmaz. Dolayısıyla cevap yalnızca Unix için geçerlidir.
The Godfather

2
Windows çözümüne ihtiyacınız varsa lütfen bu stackoverflow.com/questions/27972776/… yanıta bakın .
The Godfather

1
@TheGodfather: dizin bağlantısı bir sembolik bağlantı ( IO_REPARSE_TAG_SYMLINK) değil.
jfs

13

Python 3.4 ve üstü için Path sınıfını kullanabilirsiniz

from pathlib import Path


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

İs_symlink () yöntemini kullanırken dikkatli olmalısınız. Adlandırılan nesne bir sembolik bağ olduğu sürece, bağlantının hedefi mevcut olmasa bile True döndürür. Örneğin (Linux / Unix):

ln -s ../nonexistentfile flnk

Ardından, mevcut dizininizde python'u ateşleyin

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

Programcı gerçekte ne istediğine karar vermelidir. Python 3 birçok sınıfı yeniden adlandırmış gibi görünüyor. Path sınıfının kılavuz sayfasını okumak faydalı olabilir: https://docs.python.org/3/library/pathlib.html


bu yalnızca geçerli bir sembolik bağ bulabilir, bu bir sembolik bağ olan ancak bozuk olan bir dosyayı tanımlamayabilir. bu nedenle, gerçek dosyaları veya tüm sembolik bağlantıları (iyi ve kötü)
filtreliyorsanız,

@ 2114L3 Geçerli ancak bozuk bir sembolik bağ ne anlama geliyor? Kırık bir sembolik bağlantı ile basit testlerden, bu is_symlink()doğru ve exists()yanlış gibi görünüyor , ki bu da beklediğim şey. Endişeleriniz için bir kaynak verebilir misiniz?
Jonathan H

1
@Sheljohn, yorumum var olmadan önce bu cevapla ilgili düzenlemeleri kontrol et () cevabın bir parçası değildi. kullanımı var demek istediğim ek bir kontrol. tek başına is_symlink kullanımı orijinal versiyona göre yeterli değildir.
2114L3

Windows'ta bu benim için düzgün çalışmıyor: var olmayan dosyalar için is_symlinkgeri dönüyor true(bu yüzden exists()geri dönüyor true).
James Hirschorn

3

Bu konuyu şişirmek gibi bir niyetim olmadı, ancak onları bulup gerçek dosyalara dönüştürmek için symlink'leri ararken bu sayfaya yönlendirildim ve bu komut dosyasını python araçları kitaplığında buldum.

#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")

Burada neler olduğunu açıklayabilir misin? Aslında geri yazmadan önce dosyayı kaldırdığınız (bağlantısını kaldırdığınız) göründüğü için biraz tuhaf görünüyor . Bu nasıl olabilir? Ayrıca sonuncusu mkrealfile(...)kendi işlevi ile aynı seviyede ...
not2qubit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.