「スクリプトの中でシンボリックリンクを辿って絶対パスを取得したいが、どうすればいいか」
Linuxを使っていると、シンボリックリンクが関係するトラブルに何度か遭遇します。
アプリケーションがリンク先のファイルを見つけられない、スクリプトがシンボリックリンクを辿れずにエラーになる、といったケースは現場でよく見かけます。
この記事では、
readlink コマンドの実践的な使い方を解説します。基本的なリンク先確認から、
-f オプションを使った絶対パスの完全解決、シェルスクリプトでの活用まで幅広くカバーします。この記事のポイント
・readlink でシンボリックリンクのリンク先パスを表示できる
・readlink -f で多段リンクも辿り絶対パスを完全解決できる
・スクリプト内でのself-path取得に readlink -f $0 が定番
・リンク先が存在しない場合の挙動の違いに注意が必要
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
readlinkコマンドとは
readlink はシンボリックリンクが指し示すパス(リンク先)を表示するコマンドです。GNU coreutilsに含まれており、RHEL / AlmaLinux / Ubuntu などすべての主要Linuxディストリビューションで標準で使えます。
「
ls -la で確認すればリンク先はわかるじゃないか」と思う方もいるかもしれません。しかし
ls -la の出力をスクリプトで処理するのは面倒です。readlink はリンク先パスだけをシンプルに出力するので、スクリプトに直接組み込めるのが最大の強みです。また
-f オプションを使うと、シンボリックリンクが複数段重なっていても最終的な実体ファイルの絶対パスを返してくれます。これが非常に強力で、現場では
readlink と言えば readlink -f のことを指すケースが多いくらいです。動作確認環境
この記事の内容は以下の環境で動作確認しています。# AlmaLinux 9.4 / Ubuntu 24.04 LTS で動作確認済み # readlink のバージョン確認 readlink --version
readlink (GNU coreutils) 8.32 Copyright (C) 2020 Free Software Foundation, Inc.
基本的な使い方
1. シンボリックリンクのリンク先を表示する
まずreadlink の基本的な使い方を確認します。以下のようなシンボリックリンクが存在する状況を例にします。
# テスト用のファイルとシンボリックリンクを作成 echo "実体ファイル" > /tmp/original.txt ln -s /tmp/original.txt /tmp/link.txt # ls -la でリンク先を確認 ls -la /tmp/link.txt
lrwxrwxrwx. 1 admin admin 16 May 7 10:00 /tmp/link.txt -> /tmp/original.txt
ls -la では -> の右側にリンク先が表示されますが、これをスクリプトで取り出すのは手間がかかります。readlink ならリンク先のパスだけを出力できます。# readlink でリンク先のパスを表示 readlink /tmp/link.txt
/tmp/original.txt
スクリプト変数への代入も簡単です。
# 変数に代入して活用 LINK_TARGET=$(readlink /tmp/link.txt) echo "リンク先: ${LINK_TARGET}"
リンク先: /tmp/original.txt
2. 通常ファイルに対して実行した場合
シンボリックリンクではなく通常のファイルやディレクトリに対してreadlink を実行すると、何も出力せずに終了コード1を返します。# 通常ファイルに対して実行 readlink /tmp/original.txt echo "終了コード: $?"
(何も出力されない) 終了コード: 1
# シンボリックリンクかどうかを判定するスクリプト例 FILE="/tmp/link.txt" if [ -L "${FILE}" ]; then echo "${FILE} はシンボリックリンクです" echo "リンク先: $(readlink ${FILE})" else echo "${FILE} は通常ファイルまたはディレクトリです" fi
-L 判定(シンボリックリンクかどうか)は [ ] の組み込みテストを使うのが標準的です。-f オプションで絶対パスを完全解決する
1. -f オプションの基本動作
readlink -f は多段シンボリックリンクをすべて辿り、最終的な実体ファイルの絶対パスを返します。現場でよく使う場面はこちらです。
# 多段シンボリックリンクの準備 echo "実体" > /tmp/real_file.txt ln -s /tmp/real_file.txt /tmp/link1.txt ln -s /tmp/link1.txt /tmp/link2.txt ln -s /tmp/link2.txt /tmp/link3.txt # readlink(-fなし)は直近のリンク先だけを返す readlink /tmp/link3.txt
/tmp/link2.txt
# readlink -f は最終的な実体ファイルまで完全解決する readlink -f /tmp/link3.txt
/tmp/real_file.txt
-f なしの readlink は「直接の」リンク先しか返しません。多段リンクを辿り切るには必ず
-f を使ってください。2. 相対パスのシンボリックリンクにも対応
シンボリックリンクは絶対パスだけでなく相対パスで作られることもあります。readlink -f はどちらの場合も正しく絶対パスに解決します。# 相対パスのシンボリックリンクを作成 mkdir -p /tmp/testdir echo "実体" > /tmp/testdir/real.txt cd /tmp/testdir ln -s real.txt relative_link.txt # readlink(-fなし)は相対パスをそのまま返す readlink /tmp/testdir/relative_link.txt
real.txt
# readlink -f は絶対パスに解決して返す readlink -f /tmp/testdir/relative_link.txt
/tmp/testdir/real.txt
readlink -f で絶対パスに変換しておくと安全です。3. 通常ファイルに対して -f を使った場合
readlink -f は通常ファイルやディレクトリに対しても使えます。シンボリックリンクではなくても、そのファイルの絶対パスを返します。
# 通常ファイルに対して -f を使う readlink -f /tmp/original.txt
/tmp/original.txt
実務での活用例
1. スクリプト自身の場所を取得する(定番パターン)
シェルスクリプトを書く際の定番イディオムが「スクリプト自身の絶対パスを取得する」処理です。スクリプトをどのディレクトリから実行しても、スクリプトと同じディレクトリにある設定ファイルや他のスクリプトを正しく参照できます。
#!/bin/bash # スクリプト自身の絶対パスを取得する定番パターン SCRIPT_PATH=$(readlink -f "$0") SCRIPT_DIR=$(dirname "${SCRIPT_PATH}") echo "スクリプトのパス: ${SCRIPT_PATH}" echo "スクリプトのディレクトリ: ${SCRIPT_DIR}" # 同じディレクトリにある設定ファイルを読み込む CONFIG_FILE="${SCRIPT_DIR}/config.conf" if [ -f "${CONFIG_FILE}" ]; then source "${CONFIG_FILE}" fi
$0 はスクリプト自身のパスを示しますが、相対パスや ../ を含む場合があります。readlink -f "$0" で絶対パスに解決することで、どこから呼び出されても同じ動きをするスクリプトになります。2. /usr/bin/ のコマンドが実体はどこにあるか確認する
AlmaLinux / RHEL 環境では多くのコマンドがシンボリックリンク経由で提供されています。python3 や java などの実体がどこにあるかを確認するのに便利です。# python3 の実体を確認 readlink -f $(which python3)
/usr/bin/python3.11
# alternatives で管理されているコマンドの場合 readlink -f $(which java)
/usr/lib/jvm/java-17-openjdk-17.0.11.0.9-2.el9.x86_64/bin/java
alternatives(update-alternatives)で管理されているコマンドは複数段のシンボリックリンクになっています。readlink -f で一発で実体パスを確認できます。3. ログローテーション後のファイル確認
logrotate でログファイルをローテーションしている環境で、現在の実際のログファイルがどこにあるかを確認する場合にも使えます。# nginx のアクセスログの実体パスを確認 readlink -f /var/log/nginx/access.log
/var/log/nginx/access.log
スクリプトで「リンクかどうかわからないが絶対パスが欲しい」場合に安心して使えます。
4. /etc/alternatives 配下の設定確認
サーバー管理者が特によく使うのが/etc/alternatives 配下のリンク確認です。# /etc/alternatives 配下のリンクを確認 ls -la /etc/alternatives/python3
lrwxrwxrwx. 1 root root 23 Jan 15 09:32 /etc/alternatives/python3 -> /usr/bin/python3.11
# readlink -f で最終的な実体まで解決 readlink -f /etc/alternatives/python3
/usr/bin/python3.11
その他のオプション
readlink には -f 以外にも関連オプションがあります。1. -e オプション(存在チェック付き絶対パス解決)
-e オプションは -f と同様に多段リンクを解決しますが、最終的な実体ファイルが存在しない場合はエラーを返して何も出力しません。# 実体が存在するシンボリックリンク readlink -e /tmp/link.txt
/tmp/original.txt
# 実体が存在しないシンボリックリンク(ダングリングリンク) ln -s /tmp/not_exist.txt /tmp/dangling_link.txt readlink -e /tmp/dangling_link.txt echo "終了コード: $?"
(何も出力されない) 終了コード: 1
-f は実体が存在しない場合でも、リンクが指すパスを正規化して返します。# -f はダングリングリンクでもパスを返す readlink -f /tmp/dangling_link.txt echo "終了コード: $?"
/tmp/not_exist.txt 終了コード: 0
-e を、「存在確認は別途行うのでとにかくパスを解決したい」場合は -f を使い分けてください。2. -m オプション(存在しないパスでも解決)
-m オプションはパスの各要素が存在しなくても、シンボリックリンクを辿ってパスを解決します。ファイルを作成する前に絶対パスを決定したい場合などに使います。
# まだ存在しないパスの絶対パスを解決 readlink -m /tmp/not_yet_created/file.txt
/tmp/not_yet_created/file.txt
トラブルシュート・よくある疑問
「readlink: missing operand」と表示される
引数(ファイルパス)なしでreadlink を実行するとこのエラーが出ます。# エラーが出る例 readlink
readlink: missing operand Try 'readlink --help' for more information.
シンボリックリンクに対して readlink が何も返さない
readlink(オプションなし)は対象がシンボリックリンクでない場合、何も出力しません。対象がシンボリックリンクかどうかを確認するには
ls -la や [ -L ファイル名 ] で確認してください。# シンボリックリンクかどうか確認する方法 if [ -L "/path/to/file" ]; then echo "シンボリックリンクです" readlink "/path/to/file" else echo "シンボリックリンクではありません" fi
macOS での readlink は動きが違う
macOS に標準でインストールされているreadlink はBSD版であり、-f オプションが使えません。macOSで同等の機能を使うには
brew install coreutils でGNUバージョン(greadlink)をインストールするか、python3 -c "import os; print(os.path.realpath('/path/to/link'))" で代替します。Linuxサーバーでの作業では問題ありませんが、Mac上でスクリプトを開発してLinuxにデプロイする際は注意してください。
ダングリングリンク(実体がないシンボリックリンク)を検出する
find コマンドと組み合わせると、ディレクトリ内のダングリングリンクを一括で検出できます。# ダングリングリンクを検出する find /tmp -type l | while read LINK; do if [ ! -e "${LINK}" ]; then echo "ダングリングリンク: ${LINK} -> $(readlink ${LINK})" fi done
ダングリングリンク: /tmp/dangling_link.txt -> /tmp/not_exist.txt
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| シンボリックリンクの直接のリンク先を表示 | readlink リンクファイル |
| 多段リンクを辿って絶対パスを解決 | readlink -f リンクファイル |
| 実体が存在する場合のみ絶対パスを解決 | readlink -e リンクファイル |
| 存在確認なしで絶対パスを解決 | readlink -m パス |
| スクリプト自身の絶対パスを取得 | readlink -f "$0" |
| コマンドの実体パスを確認 | readlink -f $(which コマンド名) |
| ダングリングリンクを検出 | find パス -type l | while read L; do [ ! -e "$L" ] && echo "$L"; done |
readlink は地味なコマンドですが、シェルスクリプトの品質を大きく左右します。特に
readlink -f "$0" によるスクリプト自身のパス取得は、どのディレクトリから実行されても正しく動くスクリプトを書くための基本テクニックです。シンボリックリンクを多用するLinux環境では、
readlink -f を使いこなせるかどうかがスクリプトの堅牢性に直結します。ぜひ日常の作業に取り入れてみてください。
なお、シンボリックリンクを使ったファイルシステム管理について詳しく学びたい方は、mount コマンドの使い方や ls コマンドの基本オプションの記事もあわせてご覧ください。
また、Linux全般のコマンド体系をより深く理解したい方は Linux 基本コマンドの解説が参考になります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、無料のメールマガジン「Linux Master Magazine」をお届けしています。
現役サーバー管理者として20年以上の現場経験をもとに、コマンドの使い方から実務トラブルの対処まで、現場で本当に使える技術情報をお伝えしています。
>> 無料メールマガジンに登録する(登録特典:Linuxサーバー構築入門マニュアル60P)
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:columnコマンドでテキストを表形式に整形する方法|TSVやログをきれいに揃える実践例も
- 前のページへ:dateコマンドでLinuxの日時を操作する方法|フォーマット変換・計算・シェルスクリプト活用も
- この記事の属するカテゴリ:Linuxtipsへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます