readlinkコマンドとは?Linuxでシンボリックリンクのリンク先を確認する方法

Linux

Linuxでシンボリックリンクを見つけたとき、「このリンクはどこを参照しているのか」「相対パスではなく絶対パスで確認したい」と思うことがあります。

そのようなときに使うのがreadlinkコマンドです。

readlinkコマンドを使うと、シンボリックリンクに記録されているパスをそのまま表示したり、-fオプションで参照先を絶対パスに変換したりできます。また、-eを使えば、参照先を含むパス全体が実際に存在するかどうかの確認にも利用できます。

最初に、よく使う形を確認しておきましょう。

readlink リンク名
readlink -f リンク名
readlink -e リンク名
  • readlink リンク名:リンクに記録されたパスをそのまま表示する
  • readlink -f リンク名:シンボリックリンクをたどり、正規化した絶対パスを表示する
  • readlink -e リンク名:パスの全構成要素が存在する場合だけ、正規化した絶対パスを表示する

この記事では、Linux初心者でもコピペして試せるように、練習環境の準備から基本操作、-f-e-mの違い、リンク切れの見つけ方、シェルスクリプトでの安全な使い方、エラー対処まで順番に解説します。

  1. readlinkコマンドとは?
  2. 練習用のシンボリックリンクを準備する
  3. シンボリックリンクに記録されたリンク先を確認する
  4. readlink -fでリンク先を絶対パスに変換する
  5. readlink -f・-e・-mの違い
    1. readlink -fの動作
    2. readlink -eの動作
    3. readlink -mの動作
  6. 相対リンクと絶対リンクをreadlinkで確認する
    1. 相対パスが記録されたリンク
    2. 絶対パスが記録されたリンク
  7. 複数段のシンボリックリンクを確認する
  8. リンク切れを確認する方法
    1. readlinkで記録されたパスを確認する
    2. readlink -eと終了ステータスで確認する
    3. testコマンドと組み合わせて確認する
  9. readlinkコマンドの主なオプション
  10. 複数のシンボリックリンクを確認する
  11. シェルスクリプトでreadlinkを使う方法
    1. リンク先を取得できた場合だけ処理する
    2. 実在する最終的な参照先を取得する
  12. readlink・ls -l・realpath・statの違い
  13. readlinkコマンドでよくある問題と対処法
    1. 何も表示されない
    2. readlink -fで表示されたのにファイルを開けない
    3. Permission deniedと表示される
    4. Too many levels of symbolic linksと表示される
    5. 相対パスが想定と違う場所を指している
  14. readlinkコマンドを使うときの注意点
  15. よくある質問
    1. readlinkコマンドは何をするコマンドですか?
    2. readlinkとreadlink -fの違いは何ですか?
    3. readlink -fとreadlink -eの違いは何ですか?
    4. リンク切れでもreadlinkの結果は表示されますか?
    5. 通常のファイルにreadlinkを実行するとどうなりますか?
    6. ディレクトリへのシンボリックリンクにも使えますか?
    7. readlinkでシンボリックリンクを作成できますか?
    8. パスの絶対パス化にはreadlinkとrealpathのどちらを使えばよいですか?
  16. まとめ

readlinkコマンドとは?

readlinkコマンドは、シンボリックリンクに記録されたリンク先や、正規化したファイルパスを表示するコマンドです。

基本書式は次のとおりです。

readlink [オプション] ファイル名

オプションを付けない場合、指定したシンボリックリンクの中に記録されている文字列を表示します。

たとえば、sample-link.txtdata/sample.txtという相対パスが記録されている場合は、次のように表示されます。

readlink sample-link.txt
data/sample.txt

この結果は、参照先を絶対パスへ変換したものではありません。シンボリックリンクに保存されているパスを、そのまま読み出した結果です。

また、オプションなしで通常のファイルを指定すると、基本的に何も表示せず、終了ステータスは0以外になります。readlinkは、ファイルの内容を表示するcatとは役割が異なります。

練習用のシンボリックリンクを準備する

readlinkコマンドの動きを確認するため、ホームディレクトリに練習環境を作成します。

cd ~
mkdir -p readlink-practice/real
echo "Hello Linux" > readlink-practice/real/sample.txt
cd readlink-practice

次に、ファイルとディレクトリを参照するシンボリックリンクを作成します。

ln -s real/sample.txt sample-link.txt
ln -s real data-link

リンク切れの確認に使うため、存在しないファイルを参照するリンクも作成します。

ln -s real/missing.txt broken-link.txt

シンボリックリンクの一覧を確認します。

ls -l

実行結果の例は次のとおりです。

lrwxrwxrwx 1 user user  4 Jul 14 10:00 data-link -> real
lrwxrwxrwx 1 user user 16 Jul 14 10:00 broken-link.txt -> real/missing.txt
lrwxrwxrwx 1 user user 15 Jul 14 10:00 sample-link.txt -> real/sample.txt
drwxr-xr-x 2 user user 24 Jul 14 10:00 real

これで、通常のリンク、ディレクトリへのリンク、リンク切れの3種類を試せる状態になりました。

シンボリックリンクに記録されたリンク先を確認する

まずは、オプションを付けずにreadlinkコマンドを実行します。

readlink sample-link.txt

次のように表示されます。

real/sample.txt

sample-link.txtを作成するときに指定した相対パスが、そのまま表示されています。

ディレクトリへのシンボリックリンクも、同じ方法で確認できます。

readlink data-link
real

readlinkは、参照先がファイルかディレクトリかに関係なく、リンクに記録されたパスを表示します。

readlink -fでリンク先を絶対パスに変換する

相対パスではなく、シンボリックリンクをたどった先の絶対パスを確認したい場合は、-fオプションを使用します。

readlink -f sample-link.txt

実行結果の例は次のとおりです。

/home/user/readlink-practice/real/sample.txt

-fは、パスに含まれるシンボリックリンクを再帰的にたどり、次の要素を整理した絶対パスを表示します。

  • .で表される現在のディレクトリ
  • ..で表される親ディレクトリ
  • 重複した/
  • パス途中に含まれるシンボリックリンク

たとえば、次のようなパスも正規化できます。

readlink -f ./data-link/../real/sample.txt

ただし、GNU Coreutilsのreadlink -fでは、指定したパスの最後以外の構成要素が存在している必要があります。最後のファイル名だけが存在しない場合は、その存在しない名前を含む絶対パスが表示されることがあります。

そのため、readlink -fでパスが表示されたからといって、参照先が必ず存在するとは限りません。

readlink -f・-e・-mの違い

readlinkコマンドで特に迷いやすいのが、-f-e-mの違いです。

オプション 存在条件 主な用途
-f
--canonicalize
最後以外の構成要素が存在する必要がある 一般的なパスの正規化、リンク先の絶対パス確認
-e
--canonicalize-existing
すべての構成要素が存在する必要がある 実在するリンク先の確認、リンク切れの検出
-m
--canonicalize-missing
構成要素が存在しなくてもよい まだ作成していないパスを含む絶対パスの組み立て

readlink -fの動作

存在するリンクを指定すると、参照先を絶対パスで表示します。

readlink -f sample-link.txt
/home/user/readlink-practice/real/sample.txt

今回作成したリンク切れを指定した場合も、親ディレクトリのrealが存在するため、最後のmissing.txtを含むパスが表示されます。

readlink -f broken-link.txt
/home/user/readlink-practice/real/missing.txt

この結果だけでは、missing.txtが実在するかどうかを判断できません。

readlink -eの動作

-eは、パスを構成するすべての要素が存在する場合だけ結果を表示します。

readlink -e sample-link.txt
/home/user/readlink-practice/real/sample.txt

リンク切れを指定すると、何も表示されず、終了ステータスが0以外になります。

readlink -e broken-link.txt
echo $?

実行結果の例は次のとおりです。

1

参照先が実在することまで確認したい場合は、-fではなく-eが適しています。

readlink -mの動作

-mは、パスの一部または全部が存在しなくても、正規化した絶対パスを表示します。

readlink -m future/backup/sample.txt

実行結果の例は次のとおりです。

/home/user/readlink-practice/future/backup/sample.txt

futurebackupディレクトリが存在していなくても、結果を取得できます。

これから作成する保存先のパスをシェルスクリプト内で整理したい場合には便利ですが、-mはファイルやディレクトリの存在を保証しません。

相対リンクと絶対リンクをreadlinkで確認する

シンボリックリンクには、相対パスまたは絶対パスが記録されています。readlinkをオプションなしで実行すると、その違いを確認できます。

相対パスが記録されたリンク

readlink sample-link.txt
real/sample.txt

相対リンクは、現在のシェルの作業ディレクトリではなく、シンボリックリンクが置かれているディレクトリを基準に解決されます。

絶対パスが記録されたリンク

絶対パスを使ったリンクを作成します。

ln -s "$(pwd)/real/sample.txt" absolute-link.txt
readlink absolute-link.txt

実行結果の例は次のとおりです。

/home/user/readlink-practice/real/sample.txt

この場合は、リンク内に絶対パスが記録されているため、オプションなしでも/から始まるパスが表示されます。

相対リンクか絶対リンクかに関係なく、最終的な正規化済みパスを確認したい場合は、次のように-fまたは-eを使います。

readlink -e sample-link.txt
readlink -e absolute-link.txt

複数段のシンボリックリンクを確認する

シンボリックリンクが、別のシンボリックリンクを参照していることもあります。

sample-link.txtを参照する2段目のリンクを作成します。

ln -s sample-link.txt second-link.txt

オプションなしでは、2段目のリンクに直接記録されたパスだけが表示されます。

readlink second-link.txt
sample-link.txt

-fまたは-eを付けると、リンクを順番にたどった最終的な参照先が表示されます。

readlink -e second-link.txt
/home/user/readlink-practice/real/sample.txt

「リンクに直接何が書かれているか」を知りたい場合はオプションなし、「最終的にどこへ到達するか」を知りたい場合は-fまたは-eという使い分けになります。

リンク切れを確認する方法

シンボリックリンクは、参照先が削除または移動されてもリンク自体は残ります。この状態をリンク切れ、壊れたリンク、broken symlinkなどと呼びます。

今回作成したbroken-link.txtは、存在しないreal/missing.txtを参照しています。

readlinkで記録されたパスを確認する

readlink broken-link.txt
real/missing.txt

通常のreadlinkは、参照先が存在しなくても、リンクに記録された値を表示できます。そのため、この結果だけではリンク切れかどうかは分かりません。

readlink -eと終了ステータスで確認する

readlink -e broken-link.txt
echo $?

結果が表示されず、終了ステータスが0以外であれば、パスのどこかが存在しないか、アクセスできない状態です。

testコマンドと組み合わせて確認する

シンボリックリンクであり、なおかつ参照先が存在しないことを明確に判定する場合は、次のように記述できます。

link="broken-link.txt"

if [ -L "$link" ] && [ ! -e "$link" ]; then
  echo "$link はリンク切れです"
fi
  • -L:指定した名前がシンボリックリンクなら真
  • -e:参照先が存在すれば真

この2つを組み合わせることで、通常の存在しないファイルとリンク切れしたシンボリックリンクを区別できます。

readlinkコマンドの主なオプション

オプション 意味 使用例
-f
--canonicalize
リンクをたどり、正規化した絶対パスを表示する。最後以外は存在が必要 readlink -f link
-e
--canonicalize-existing
すべての構成要素が存在する場合だけ絶対パスを表示する readlink -e link
-m
--canonicalize-missing
存在しない構成要素を含めて絶対パスを生成する readlink -m path
-n
--no-newline
1つのファイルを指定したとき、末尾の区切り文字を出力しない readlink -n link
-q-s
--quiet--silent
多くのエラーメッセージを表示しない readlink -q link
-v
--verbose
エラー内容を表示する readlink -v link
-z
--zero
改行ではなくNUL文字で出力を区切る readlink -z link

-zは、改行を含む特殊なファイル名も安全に別のコマンドへ渡す必要がある処理で使用されます。通常の手作業では、まずreadlinkreadlink -freadlink -eの3つを覚えておけばよいでしょう。

複数のシンボリックリンクを確認する

GNU Coreutilsのreadlinkでは、複数のファイル名を指定できます。

readlink sample-link.txt data-link second-link.txt

結果は指定した順番に1行ずつ表示されます。

real/sample.txt
real
sample-link.txt

ただし、通常の出力には元のリンク名が付かないため、リンク数が多いと対応関係が分かりにくくなります。

リンク名と参照先をセットで表示したい場合は、シェルの繰り返し処理を使うと分かりやすくなります。

for link in sample-link.txt data-link second-link.txt; do
  printf '%s -> %s\n' "$link" "$(readlink -- "$link")"
done

実行結果は次のようになります。

sample-link.txt -> real/sample.txt
data-link -> real
second-link.txt -> sample-link.txt

--は、後ろに続く値をオプションではなくファイル名として扱わせるための記述です。ファイル名が-から始まる可能性があるスクリプトで役立ちます。

シェルスクリプトでreadlinkを使う方法

readlinkは、設定ファイルや実行中のスクリプトが実際に置かれている場所を確認する処理などで利用できます。

リンク先を取得できた場合だけ処理する

link="sample-link.txt"

if target=$(readlink -- "$link"); then
  printf 'リンク先: %s\n' "$target"
else
  printf 'シンボリックリンクを読み取れません: %s\n' "$link" >&2
fi

readlinkが成功したときは終了ステータス0、失敗したときは0以外を返します。単に出力が空かどうかを見るより、終了ステータスで成功・失敗を判断するほうが確実です。

実在する最終的な参照先を取得する

link="sample-link.txt"

if target=$(readlink -e -- "$link"); then
  printf '実在する参照先: %s\n' "$target"
else
  printf '参照先が存在しないか、アクセスできません\n' >&2
fi

ファイル名や変数は、空白やワイルドカード文字を含む可能性があります。"$link"のように変数をダブルクォートで囲むことが大切です。

readlink・ls -l・realpath・statの違い

コマンド 主に確認できること 向いている場面
readlink シンボリックリンクに記録されたパス リンク先の値だけを取得したい
readlink -e 実在する最終参照先の正規化済み絶対パス リンクをたどった先の存在も確認したい
ls -l 種類、権限、所有者、リンク名、参照先 人がリンクの状態を一覧で確認したい
realpath 正規化した絶対パス 通常ファイルを含むパス全般を正規化したい
stat 種類、権限、inode、時刻などの詳細情報 ファイルやリンクのメタデータを調べたい

GNU Coreutilsの公式マニュアルでは、パスの正規化だけが目的ならrealpathコマンドの使用が推奨されています。

シンボリックリンクに直接記録された値を読みたい場合はreadlink、通常のパスを絶対パスへ変換したい場合はrealpathという使い分けが分かりやすいでしょう。

readlink sample-link.txt
realpath sample-link.txt

実行結果の例は次のとおりです。

real/sample.txt
/home/user/readlink-practice/real/sample.txt

readlinkコマンドでよくある問題と対処法

何も表示されない

オプションなしのreadlinkで何も表示されない場合は、指定した名前がシンボリックリンクではないか、ファイル自体が存在しない可能性があります。

ls -ld 対象名
test -L 対象名
echo $?

test -Lの終了ステータスが0ならシンボリックリンク、0以外ならシンボリックリンクではありません。

エラー内容も確認したい場合は、-vを付けます。

readlink -v 対象名

readlink -fで表示されたのにファイルを開けない

-fは、最後の構成要素だけが存在しない場合でもパスを表示できます。そのため、表示されたパスの実在を確認するには-eを使います。

readlink -e 対象名

または、test -eで存在を確認します。

test -e 対象名
echo $?

Permission deniedと表示される

パス途中のディレクトリを通過する権限がない可能性があります。ディレクトリの所有者と権限を確認します。

ls -ld /path /path/to /path/to/directory

権限を変更する前に、そのディレクトリを管理しているユーザーやサービスへの影響を確認してください。

Too many levels of symbolic linksと表示される

シンボリックリンクが循環している可能性があります。

ln -s link-b link-a
ln -s link-a link-b

このように、互いを参照すると最終的なリンク先へ到達できません。まず各リンクに直接記録された値を確認します。

readlink link-a
readlink link-b

循環しているリンクを削除し、正しい参照先で作り直してください。

相対パスが想定と違う場所を指している

相対リンクは、シンボリックリンクが存在するディレクトリを基準に解決されます。リンクが置かれた場所と記録された値を確認してください。

ls -ld シンボリックリンク
readlink シンボリックリンク
readlink -e シンボリックリンク

readlink -eで結果が出ない場合は、記録された相対パスが正しいか、参照先が存在するかを確認します。

readlinkコマンドを使うときの注意点

  • オプションなしでは、記録されたパスを表示するだけで存在確認はしない
  • -fの結果が出ても、最後のファイルが存在するとは限らない
  • 参照先の存在まで確認するなら-eを使う
  • -mの結果は、パスが実在することを意味しない
  • 相対リンクは、リンクが置かれたディレクトリを基準に考える
  • スクリプトでは終了ステータスを確認する
  • ファイル名や変数はダブルクォートで囲む

特に、readlink -fをリンク切れ判定に使ってしまう間違いには注意が必要です。最後の構成要素が存在しないだけなら成功することがあるため、目的に応じて-etest -eを使用してください。

よくある質問

readlinkコマンドは何をするコマンドですか?

シンボリックリンクに記録された参照先のパスを表示するコマンドです。-f-e-mを付けると、パスを正規化して絶対パスで表示するモードになります。

readlinkとreadlink -fの違いは何ですか?

オプションなしのreadlinkは、リンクに記録された文字列をそのまま表示します。readlink -fはシンボリックリンクをたどり、...などを整理した絶対パスを表示します。

readlink -fとreadlink -eの違いは何ですか?

-fは最後の構成要素が存在しなくても成功する場合があります。-eはすべての構成要素が存在する場合だけ成功します。参照先が実在することまで確かめたい場合は-eを使います。

リンク切れでもreadlinkの結果は表示されますか?

オプションなしのreadlinkでは表示されます。リンク自体に記録されたパスを読むため、参照先が存在しなくても結果を取得できます。リンク切れを判定するには、readlink -eまたは[ -L "$link" ] && [ ! -e "$link" ]を利用します。

通常のファイルにreadlinkを実行するとどうなりますか?

オプションなしでは、通常は何も表示せず、終了ステータスが0以外になります。ただし、-fなどの正規化オプションを付けた場合は、通常ファイルの正規化済みパスを表示できます。

ディレクトリへのシンボリックリンクにも使えますか?

はい、使えます。readlink ディレクトリへのリンクで記録された参照先を確認でき、readlink -eで実在する最終参照先を絶対パスで確認できます。

readlinkでシンボリックリンクを作成できますか?

いいえ、readlinkはリンク先を読み取るコマンドです。シンボリックリンクを作成する場合は、ln -s リンク元 リンク名を使用します。

パスの絶対パス化にはreadlinkとrealpathのどちらを使えばよいですか?

シンボリックリンクに記録された値を確認するならreadlinkが適しています。通常のファイルを含むパス全般を正規化するだけなら、GNU Coreutilsで推奨されているrealpathが分かりやすい選択です。

まとめ

readlinkコマンドを使うと、Linuxのシンボリックリンクに記録されたリンク先や、リンクをたどった最終的な絶対パスを確認できます。

  • readlink リンク名で記録されたパスをそのまま表示する
  • readlink -f リンク名で正規化した絶対パスを表示する
  • -fは最後の構成要素が存在しなくても成功する場合がある
  • readlink -e リンク名はすべての構成要素が存在する場合だけ成功する
  • readlink -m パスは存在しない構成要素を含めて絶対パスを生成する
  • リンク切れの判定には-eまたはtestコマンドを利用する
  • 相対リンクはリンクが置かれたディレクトリを基準に解決される
  • スクリプトでは出力だけでなく終了ステータスも確認する
  • 一般的なパスの正規化だけが目的ならrealpathも選択肢になる

まずはreadlinkでリンクに記録された値を確認し、次にreadlink -eで実在する最終的な参照先を確認してみましょう。-f-e-mの違いを理解すると、手作業だけでなくシェルスクリプトでもシンボリックリンクを安全に扱いやすくなります。

コメント

タイトルとURLをコピーしました