シェルスクリプト内でスクリプト自身のファイルパスを絶対パスで取得するしたいことがあります。実現する方法はいくつかありますが、シンボリックリンクを解決するかどうかで違いがあります。
スクリプトファイルを作成する
比較用に /tmp/hoge/a.sh
というスクリプトファイルを作成します。
/tmp/hoge/a.sh
echo "$(readlink -f "$0")"
echo "$(realpath "$0")"
echo "$(cd "$(dirname "$0")" && echo "$(pwd)/$(basename "$0")")"
シンボリックリンクを作成する
シンボリックリンクを含む場合も検証するため、以下のようにシンボリックリンクを作成します。
$ tree /tmp/
/tmp/
├── hoge
│ ├── a.sh
│ └── link-to-a.sh -> a.sh
├── link-to-hoge -> hoge/
:
/tmp/hoge/a.sh を実行する
どの方法も同じ結果です。
$ cd /tmp/hoge/
$ bash a.sh
/tmp/hoge/a.sh
/tmp/hoge/a.sh
/tmp/hoge/a.sh
/tmp/hoge/link-to-a.sh を実行する
最後の方法だけシンボリックリンクを解決しないパスを取得しています。
$ cd /tmp/hoge/
$ bash link-to-a.sh
/tmp/hoge/a.sh
/tmp/hoge/a.sh
/tmp/hoge/link-to-a.sh
/tmp/link-to-hoge/a.sh を実行する
最後の方法だけシンボリックリンクを解決しないパスを取得しています。
$ cd /tmp/link-to-hoge/
$ bash a.sh
/tmp/hoge/a.sh
/tmp/hoge/a.sh
/tmp/link-to-hoge/a.sh
/tmp/link-to-hoge/link-to-a.sh を実行する
最後の方法だけシンボリックリンクを解決しないパスを取得しています。
$ cd /tmp/link-to-hoge/
$ bash link-to-a.sh
/tmp/hoge/a.sh
/tmp/hoge/a.sh
/tmp/link-to-hoge/link-to-a.sh
結論
シェルスクリプト内でスクリプト自身のファイルパスを絶対パスを取得する場合、
- シンボリックリンクを解決したパスが必要なら
readlink
かrealpath
を使う。 - シンボリックリンクを解決しないパスが必要なら
cd
+pwd
を使う。