数学講師2858862 views
小学社会308836 views
高校日本史189951 views
中学英語809236 views
高校国語786032 views
教育149007 views
LaTeX957956 views
高校化学2914696 views
いろは2990790 views
雑学1472779 views
Help
Tools

English

Python でシンボリックリンクとハードリンクを扱う

シンボリックリンクとハードリンクは、1 つのファイルに複数の名前を付ける仕組みだ。Python ではどちらも作成・操作できる。

シンボリックリンクとハードリンクの違い

シンボリックリンク

ファイルの「パス」を指すショートカット。リンク先が削除されると壊れる(dangling link)。異なるファイルシステムを跨げる。ディレクトリにもリンクできる。

ハードリンク

同じ inode を共有する別名。どちらのリンクを削除しても、もう一方からアクセスできる。同じファイルシステム内でのみ作成可能。ディレクトリには作成できない。

シンボリックリンクを作成する

os.symlink() でシンボリックリンクを作成する。

import os

# target へのシンボリックリンクを link_name として作成
os.symlink('target.txt', 'link_to_target.txt')

pathlib でも同様に作成できる。

from pathlib import Path

Path('link_to_target.txt').symlink_to('target.txt')

ディレクトリへのシンボリックリンクを作成する場合は、target_is_directory=True を指定する(Windows で必要)。

os.symlink('mydir', 'link_to_dir', target_is_directory=True)

ハードリンクを作成する

os.link() でハードリンクを作成する。

import os

os.link('original.txt', 'hardlink.txt')

pathlib では link_to() を使う(Python 3.10 以降は hardlink_to())。

from pathlib import Path

# Python 3.10 以降
Path('hardlink.txt').hardlink_to('original.txt')

シンボリックリンクかどうかを判定する

import os
from pathlib import Path

# os.path
print(os.path.islink('link_to_target.txt'))  # True

# pathlib
print(Path('link_to_target.txt').is_symlink())  # True

シンボリックリンクの参照先を取得する

import os
from pathlib import Path

# os
target = os.readlink('link_to_target.txt')
print(target)  # target.txt

# pathlib
target = Path('link_to_target.txt').readlink()
print(target)  # target.txt

シンボリックリンクを解決する

resolve() はシンボリックリンクをたどって最終的なパスを返す。

from pathlib import Path

# link -> dir/file.txt の場合
real_path = Path('link').resolve()
print(real_path)  # /home/user/dir/file.txt

os.path.realpath() も同様だ。

import os

real_path = os.path.realpath('link')

リンクをたどらずに操作する

os.lstat() はシンボリックリンク自体の情報を返す(os.stat() はリンク先の情報を返す)。

import os

# リンク先の情報
stat_info = os.stat('link_to_target.txt')

# リンク自体の情報
lstat_info = os.lstat('link_to_target.txt')

ハードリンクの数を確認する

os.stat()st_nlink でハードリンクの数がわかる。

import os

nlinks = os.stat('original.txt').st_nlink
print(f'リンク数: {nlinks}')

通常のファイルは 1、ハードリンクを作成すると 2 以上になる。

壊れたシンボリックリンクの検出

リンク先が存在しないシンボリックリンク(dangling link)を検出する。

from pathlib import Path

def is_broken_symlink(path):
    p = Path(path)
    return p.is_symlink() and not p.exists()

# 使用例
if is_broken_symlink('link_to_target.txt'):
    print('壊れたシンボリックリンクです')

exists() はリンク先の存在を確認するが、is_symlink() はリンク自体の存在を確認する。両方を組み合わせることで壊れたリンクを検出できる。