Linuxでシンボリックリンクの参照先を確認するときは、リンクに保存されている文字列を見るのか、リンクをたどった絶対パスを得るのか、リンク先の存在まで確認するのかでコマンドを使い分けます。
保存された参照先は readlink、連鎖を解決したパスはGNU版の readlink -f、存在する経路だけを得たい場合は readlink -e が基本です。readlink をオプションなしで実行しても、必ず絶対パスになるわけではありません。以下は主にGNU coreutilsを使うLinux環境の説明です。
まず使う3つの確認コマンド
対象を /path/to/link に置き換えます。空白を含むパスに備えて引用符で囲み、-- でオプションの終わりを示します。
ls -ld -- "/path/to/link"
readlink -- "/path/to/link"
readlink -e -- "/path/to/link"
ls -ld はリンク自身の情報を目視確認する用途、オプションなしの readlink はリンクに記録された参照先、-e は経路が存在して解決できる場合の絶対パスを調べる用途です。ディレクトリへのリンクを見るときも、リンク名の末尾に不用意に / を付けないでください。
シンボリックリンクは参照先の文字列を持つ
シンボリックリンクはデータのコピーではなく、別のパスを参照する特殊なファイルです。参照先はファイルだけでなくディレクトリや、さらに別のシンボリックリンクでも構いません。存在しない参照先を持つリンクも作成でき、移動・削除後にリンク切れになることがあります。
作成構文は ln -s ターゲット リンク名 です。ただし、既存のリンクを確認したいだけなら新しく作る必要はありません。システムの実行ファイルやライブラリのリンクを、確認目的で上書きしないでください。
readlinkは保存された値を表示する:相対パスに注意
例えば、/srv/app/current に保存されている値が releases/v2 なら、オプションなしの readlink はその文字列を返します。これは説明用の例であり、そのパスが実際に存在することを示していません。
readlink -- "/srv/app/current"
# 表示例: releases/v2
相対リンクは、コマンドを実行したカレントディレクトリではなく、リンクを置いているディレクトリを基準に解決されます。この例なら /srv/app/releases/v2 を参照します。リンクだけを別の場所へ移動すると、同じ文字列でも参照先が変わる場合があります。
通常ファイルに対してオプションなしの readlink を実行すると、GNU版では出力せず非0で終了します。「出力がない=参照先が空」ではありません。対象がシンボリックリンクか、権限やパスに問題がないかも確認します。
readlink -fと-eの違い:絶対パスが出ても存在保証ではない
readlink -f -- "/path/to/link"
readlink -e -- "/path/to/link"
GNU版の -f は途中のシンボリックリンクや .. を解決しますが、最後の構成要素が存在しなくてもパスを返す場合があります。したがって、-f の出力を「実在するファイルを確認できた」と扱わないでください。
-e は経路の構成要素がすべて存在して解決できることを要求します。-m は存在しない部分も許して正規化する用途で、存在確認には向きません。コマンドの成功後でも、別プロセスによる削除・変更やアクセス権の違いはあり得ます。読めること・安全に使えることまで保証するものではありません。
絶対パスの正規化には realpath も使えます。GNU版で存在する経路を要求するなら、意図を明確にして realpath -e -- "/path/to/link" と指定します。オプションはBusyBox、BSD系、macOSなどで差があるため、その環境のヘルプを確認してください。
安全な一時フォルダーで相対リンクを試す
次は練習用ファイルだけを新しい一時ディレクトリに作る例です。既存のシステムファイルは変更しません。作成する場所は mktemp -d によって毎回変わります。
work=$(mktemp -d) || exit 1
mkdir -- "$work/data" "$work/links"
printf 'sample\n' > "$work/data/file.txt"
ln -s -- ../data/file.txt "$work/links/relative"
ln -s -- relative "$work/links/chain"
ln -s -- ../data/missing.txt "$work/links/broken"
readlink -- "$work/links/relative"
readlink -f -- "$work/links/chain"
readlink -f -- "$work/links/broken"
readlink -e -- "$work/links/broken"
printf '直前の終了コード: %s\n' "$?"
最初は ../data/file.txt、連鎖をたどった結果は一時フォルダー内の data/file.txt の絶対パスになります。壊れたリンクでは、-f が data/missing.txt の絶対パスを返す一方、-e は出力せず失敗します。終了コードは別のコマンドを実行する前に確認します。
確認用のLinux環境(GNU coreutils 9.7)で、相対リンク、2段のリンク、最終ファイルがないリンクの -f と -e、自己参照ループ、通常ファイルへの readlink の計6ケースを実行し、この違いを確認しました。権限不足やネットワークファイルシステムなど、すべての環境を検証したわけではありません。
lsの表示は目視用:色だけで判定しない
ls -ld -- "リンク名" の先頭が l ならシンボリックリンクで、通常は -> の後に保存された参照先が表示されます。日時・所有者・サイズなどは実際の環境によって異なります。
色はエイリアス、--color、LS_COLORS、端末によって変わります。「青ならリンク」「赤なら必ずリンク切れ」とは断定しません。スクリプトで ls -l の表示を空白で分割して参照先を抜き出す方法も、空白・改行などを含む名前で壊れるため避けます。
リンク切れ・権限不足・ループを調べる
参照先が解決できない原因は、削除済みファイルだけではありません。親ディレクトリの検索権限不足、マウントされていない保存先、参照先がさらに別リンクである場合、循環参照なども確認します。GNU版の readlink -e -v は失敗時の診断メッセージを見る手掛かりになります。
readlink -e -v -- "/path/to/link"
シェルでリンク自身と参照先の有無を分ける確認例です。これも権限や同時変更の影響を受けるため、結果だけで削除対象と決めないでください。
link='/path/to/link'
if [ -L "$link" ]; then
printf 'シンボリックリンクです\n'
if [ -e "$link" ]; then
printf '参照先を確認できます\n'
else
printf '参照先がない、または確認できません\n'
fi
else
printf 'シンボリックリンクとして確認できません\n'
fi
空白などを含む名前を扱うため変数を引用符で囲みます。改行を含むパスまで機械処理する場合は、GNU版のNUL区切り出力や、それを正しく受け取る処理も検討します。単純なコマンド置換は末尾の改行を除く点にも注意してください。
GUIで確認する場合と管理上の注意
GNOME Files、Dolphin、Thunarなどのファイルマネージャーを使う場合は、リンクのプロパティや参照先に関する項目を確認します。名称や表示は環境によって違うため、最終的にたどった経路が必要ならコマンドの結果と照合してください。
リンクの用途、所有者、変更理由を記録し、元ファイルの移動時は参照しているサービスやスクリプトへの影響を確認します。壊れて見えるリンクでも、後でマウントされる保存先やサービス起動後に現れる対象を指す場合があるため、一括削除せず用途を調べます。
まとめ・公式リファレンス
保存された参照先は readlink、リンク連鎖の正規化は -f、存在する経路だけを確認したいなら -e を使い分けます。相対リンクの基準はリンクの所在ディレクトリであり、表示された絶対パスだけでは存在・読み取り権限・安全性を保証できません。
GNU Coreutilsマニュアル(readlink・realpath)/GNU:lnと相対シンボリックリンク。利用中の環境では readlink --help や man readlink も確認してください。


コメント