web-dev-qa-db-ja.com

Pythonでsymlinkターゲットを取得する方法は?

Pythonを使用して、数百のシンボリックリンクが正しいかどうかを確認し、正しくない場合は再作成する必要があります。私が今していることは、私が欲しいものと持っているものの実際のパスを比較することですが、それは自動マウントでNFSを介しているので遅いです。

それ以外の場合は、コマンド「ls -l」を使用してサブプロセスを実行し、返された文字列のリストを処理します。 Pythonライブラリを使用して、より良いソリューションを好む...

Edit1:持っている:link_name -> link_targetに続いてlink_target -> a_real_file。必要なのは、link_targetではなく、link_nameからa_real_fileを抽出することです。実際のファイルが存在していなくても構いません。

Edit2:たぶん私は正しく表現しなかった。正しいシンボリックリンクとは、「リンクが存在しない場合でも、事前定義されたパスを指すリンクです」です。だから私はそれを確認する必要があります:

link_name_1 -> target_1
link_name_2 -> target_2

そのため、実際のパスではなく、ターゲットを抽出する必要があります。次に、それらを参照(辞書)と比較します。だから私の質問は次のとおりです。ターゲットパスを抽出するにはどうすればよいですか。

19
zorggy

os.readlink()の問題は、リンクの1ステップしか解決しないことです。 Aが別のリンクBにリンクし、Bリンクがダングリングしている場合があります。

$ ln -s /tmp/example/notexist /tmp/example/B
$ ln -s /tmp/example/B /tmp/example/A
$ ls -l /tmp/example
A -> /tmp/example/B
B -> /tmp/example/notexist

Pythonで、os.readlinkは最初のターゲットを提供します。

>>> import os
>>> os.readlink('A')
'/tmp/example/B'

しかし、ほとんどの場合、解決されたパスに関心があると思います。 pathlibはここで役立ちます:

>>> from pathlib import Path
>>> Path('A').resolve()
PosixPath('/tmp/example/notexist')

古いPythonバージョン:

>>> os.path.realpath('A')
'/tmp/example/notexist'
23
wim

os.readlink() を見る必要があります。

12
Armin Rigo

リンクが壊れているかどうかを判断するには、_os.walk_をテストし、壊れたリンクに対してFalseを返すos.path.exists(path)をテストします。次に、os.path.realpath(path)を使用して、リンクが指しているものを見つけることができます。
次のようなもの(未テスト):

_for root, dirs, files in os.walk('<path>'):
    for file in files:
         f = os.join(root, file)
         if os.path.islink(f) and not os.path.exists(f):
             print("Broken: {} -> {}".format(f, os.path.realpath(f)))
_
0
AChampion

ディレクトリエントリがシンボリックリンクかどうかを判断するには、次を使用します。

os.path.islink(path)

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

0
Madhavan