Kiểm tra xem tệp có phải là liên kết biểu tượng trong python không


91

Trong python, có chức năng kiểm tra xem một tệp / thư mục nhất định có phải là liên kết tượng trưng hay không? Ví dụ: đối với các tệp bên dưới, hàm trình bao bọc của tôi sẽ trả về 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

Câu trả lời:


136

Để xác định xem mục nhập thư mục có phải là liên kết tượng trưng hay không, hãy sử dụng điều này:

os.path.islink (đường dẫn)

Trả về True nếu đường dẫn tham chiếu đến mục nhập thư mục là một liên kết tượng trưng. Luôn Sai nếu các liên kết tượng trưng không được hỗ trợ.

Ví dụ, đã cho:

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
Trên Windows, Phím tắt xuất hiện dưới dạng tệp có phần mở rộng lnkos.islink('a_shortcut.lnk')trả về False.
Evgeni Sergeev

1
@EvgeniSergeev Đó là bởi vì chúng chỉ là các tệp - có thể là sự cố từ Windows 9x những ngày khi hệ thống tệp duy nhất là FAT / FAT32. Xem superuser.com/questions/347930/… này để biết tất cả các loại liên kết tượng trưng / cứng và các mối nối thư mục được hỗ trợ trên NTFS. Điều đó nói rằng, tôi vẫn không nghĩ Python hỗ trợ chúng.
jmc

9
Và islink () không hoạt động đối với các liên kết tượng trưng của Windows, tức là các đường nối. Vì vậy, câu trả lời chỉ áp dụng cho Unix.
The Godfather

2
Vui lòng tham khảo câu trả lời stackoverflow.com/questions/27972776/… này nếu bạn cần giải pháp Windows.
The Godfather

1
@TheGodfather: đường nối thư mục không phải là liên kết tượng trưng ( IO_REPARSE_TAG_SYMLINK).
jfs

11

Đối với python 3.4 trở lên, bạn có thể sử dụng lớp Path

from pathlib import Path


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

Bạn phải cẩn thận khi sử dụng phương thức is_symlink (). Nó sẽ trả về True ngay cả khi mục tiêu của liên kết không tồn tại miễn là đối tượng được đặt tên là một liên kết tượng trưng. Ví dụ (Linux / Unix):

ln -s ../nonexistentfile flnk

Sau đó, trong thư mục hiện tại của bạn, hãy kích hoạt python

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

Các lập trình viên phải quyết định những gì anh ta / cô ấy thực sự muốn. Python 3 dường như đã đổi tên rất nhiều lớp. Có thể hữu ích khi đọc trang hướng dẫn cho lớp Đường dẫn: https://docs.python.org/3/library/pathlib.html


điều này CÓ THỂ chỉ tìm thấy liên kết biểu tượng hợp lệ, điều này CÓ THỂ không xác định một tệp là liên kết biểu tượng nhưng đã bị hỏng. vì vậy nếu bạn đang lọc cho các tập tin thật hay tất cả các liên kết tượng trưng (tốt và xấu) thì đảm bảo bạn làm thêm kiểm tra
2114L3

@ 2114L3 Liên kết tượng trưng hợp lệ nhưng bị hỏng nghĩa là gì? Từ thử nghiệm đơn giản với một liên kết tượng trưng bị hỏng, có vẻ như is_symlink()đúng và exists()sai, đó là những gì tôi mong đợi. Bạn có thể cung cấp một nguồn cho mối quan tâm của bạn?
Jonathan H

1
@Sheljohn kiểm tra các chỉnh sửa trên câu trả lời này, trước khi nhận xét của tôi tồn tại () không phải là một phần của câu trả lời. sử dụng tồn tại là một kiểm tra bổ sung mà tôi muốn nói. vì chỉ sử dụng is_symlink là không đủ theo phiên bản gốc.
2114L3

Trên Windows, điều này không hoạt động chính xác đối với tôi: is_symlinkđang trả về truecho các tệp không tồn tại (vì vậy exists()cũng trả về true).
James Hirschorn

3

Không có ý định mở rộng chủ đề này, nhưng tôi đã được chuyển hướng đến trang này khi tôi đang tìm liên kết biểu tượng để tìm chúng và chuyển đổi chúng thành tệp thực và tìm thấy tập lệnh này trong thư viện công cụ 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")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.