MENU

シンボリックリンクの実体確認と壊れリンクの検出を現場で素早く行う手順

設定ファイルを編集しようとしたら実体が別の場所にあった、削除したつもりが本体ファイルを消してしまった——シンボリックリンクにまつわるトラブルは、「これはリンクか」「リンク先はどこか」を素早く把握できれば防げます。

結論から示すと、最も手っ取り早いのは ls -lareadlink -f の組み合わせです。前者でリンクを見つけ、後者で実体の絶対パスを確定します。以下、実務でそのまま使えるパターンを順に解説します。

目次

シンボリックリンクかどうかを一発で見分ける

ls -la の出力でパーミッション欄の先頭が l になっているエントリがシンボリックリンクです。ファイル名の後ろに -> でリンク先が示されます。

$ ls -la /usr/bin/python3
lrwxrwxrwx 1 root root 10 Jan 15 09:00 /usr/bin/python3 -> python3.12

パーミッション欄の lrwxrwxrwx は、先頭の l がシンボリックリンクであることを示しています。権限ビット(rwx)はリンク先ファイルの権限が実際には適用されるため、リンク自体の権限表示はほとんど意味を持ちません。

nginx の sites-enabled や Apache の設定ディレクトリも同様の構造です。

$ ls -la /etc/nginx/sites-enabled/
total 8
drwxr-xr-x 2 root root 4096 Jul 18 10:00 .
drwxr-xr-x 8 root root 4096 Jul 18 10:00 ..
lrwxrwxrwx 1 root root   34 Jul 18 10:00 default -> /etc/nginx/sites-available/default

リンク先の実体パスを正確に取得する

ls -la が示すリンク先は相対パスのことがあり、そのまま使うと混乱を招きます。実体の絶対パスを確認するには readlink -f を使います。シンボリックリンクが多段になっている場合も、最終的な実体まで再帰的に解決してくれます。

# リンク先の絶対パスを確認
$ readlink -f /usr/bin/python3
/usr/bin/python3.12

# 多段リンクも一発で解決される
$ readlink -f /usr/bin/editor
/usr/bin/nano

リンク先が存在しない(壊れたリンク)場合、readlink -f は何も出力せず終了コードが 1 になります。スクリプト内では $? で判定できます。

$ readlink -f /etc/nginx/sites-enabled/missing-conf
# 壊れたリンクの場合は何も出力されない

$ echo $?
1

stat・file コマンドで詳細を調べる

リンクのメタ情報(作成日時・inode 番号など)まで必要な場合は stat が便利です。オプションなしではリンク自体の情報を表示し、-L を付けるとリンク先(実体)の情報に切り替わります。

# リンク自体の stat を見る(-L なし)
$ stat /usr/bin/python3
  File: /usr/bin/python3 -> python3.12
  Size: 10        Blocks: 0          IO Block: 4096   symbolic link
Device: 8,1       Inode: 131075      Links: 1
...

# リンク先(実体)の stat を見る(-L あり)
$ stat -L /usr/bin/python3
  File: /usr/bin/python3
  Size: 5892984   Blocks: 11512      IO Block: 4096   regular file
...

ざっと確認するだけなら file コマンドも手軽です。

$ file /usr/bin/python3
/usr/bin/python3: symbolic link to python3.12

ディレクトリ配下のシンボリックリンクをまとめて探す

「このディレクトリにシンボリックリンクがいくつあるか」を一覧したい場合は find-type l オプションを使います。

# カレントディレクトリ以下のシンボリックリンクを列挙
$ find . -type l

# 深さを 1 階層に限定する場合
$ find . -maxdepth 1 -type l

# リンク先パスも一緒に表示する
$ find . -type l -exec ls -la {} \;

壊れたシンボリックリンク(リンク先が存在しない)だけを絞り込むには -xtype l を使います。-type l はリンクそのものを対象にしますが、-xtype l はリンクを辿った先のファイルタイプで判定するため、リンク先が消えているものだけを拾い出せます。

# 壊れたシンボリックリンクだけを見つける
$ find /etc -xtype l 2>/dev/null

# /usr 以下で壊れたリンクを探す(パッケージ削除後の残骸確認に有効)
$ find /usr -xtype l 2>/dev/null

大規模なディレクトリを走査するときは 2>/dev/null で権限エラーを抑制しておくと出力が見やすくなります。

systemd 環境での実務シーン

現代の Linux では systemctl enable でサービスを有効化すると、/etc/systemd/system/ 配下にシンボリックリンクが作成されます。サービスが本当に有効化されているかをファイルシステムレベルで確認したい場合も、リンクの確認が直接役立ちます。

# nginx が enable されているか確認(symlink の有無でわかる)
$ ls -la /etc/systemd/system/multi-user.target.wants/nginx.service
lrwxrwxrwx 1 root root 36 Jul 18 10:00 /etc/systemd/system/multi-user.target.wants/nginx.service -> /lib/systemd/system/nginx.service

# systemctl 経由でも確認できる
$ systemctl is-enabled nginx
enabled

ある運用現場では、手動でリンクを削除して systemctl enable し直してもサービスが有効にならないというトラブルが発生しました。原因は /etc/systemd/system/ 直下に残った古い壊れたリンクで、find /etc/systemd -xtype l を実行した瞬間に発見できました。

壊れたシンボリックリンクを削除・張り直す

壊れたリンクが見つかったら、rm で削除してから ln -sf で張り直します。

# 壊れたリンクを削除
$ rm /path/to/broken-link

# 新しいリンクを作成(-s でシンボリックリンク、-f で既存エントリを上書き)
# 注意: -f は実在するファイルも上書きするため、事前に ls -la で確認すること
$ ln -sf /path/to/real-target /path/to/link-name

# 作成後に確認
$ ls -la /path/to/link-name

ln -sf-f は既存エントリを強制上書きします。誤って本物のファイルを引数に指定すると上書き削除になるため、コマンドを実行する前に必ず ls -la でリンクであることを確認してください。また、リンク先には可能な限り絶対パスを指定すると、ディレクトリを移動しても意図しない相対パスの解釈ミスを防げます。

<PR>この記事に関連するおすすめ書籍

[改訂第3版]シェルスクリプト基本リファレンス

移植性の高いシェルスクリプトを書くための逆引きリファレンス。運用スクリプトの信頼性を高めたい方に。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次