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(パス)

pathがシンボリックリンクであるディレクトリエントリを参照している場合はTrueを返します。シンボリックリンクがサポートされていない場合は、常にFalseです。

たとえば、与えられた:

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
Evgeni Sergeev 2013年

1
@EvgeniSergeevこれは、それらが単なるファイルであるためです。おそらく、ファイルシステムがFAT / FAT32であるWindows 9x日からの二日酔いです。NTFSでサポートされているすべてのタイプのシンボリック/ハードリンクおよびディレクトリジャンクションについては、このsuperuser.com/questions/347930/…を参照してください。そうは言っても、Pythonがそれらをサポートしているとはまだ思いません。
jmc 2013年

9
また、islink()はWindowsシンボリックリンク、つまりジャンクションでは機能しません。したがって、答えはUnixにのみ当てはまります。
ゴッドファーザー

2
Windowsソリューションが必要な場合は、このstackoverflow.com/questions/27972776/…回答を参照してください。
ゴッドファーザー

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()偽であるように思われます。あなたの懸念の源を与えることができますか?
Jonathan H

1
@Sheljohnは、私のコメントexists()が回答の一部ではない前に、この回答の編集を確認しました。存在を使用すると、私が意味する追加のチェックです。is_symlinkを単独で使用するだけでは、元のバージョンでは不十分です。
2114L3

Windowsでは、これは私にとってis_symlinkは正しく機能していません。true存在しないファイルに対してが返されます(したがってexists()も返されますtrue)。
James Hirschorn、

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")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.