ShellScript
Bash
Linux

シェルスクリプトの絶対パスを取得する方法の比較

シェルスクリプト内でスクリプト自身のファイルパスを絶対パスで取得するしたいことがあります。実現する方法はいくつかありますが、シンボリックリンクを解決するかどうかで違いがあります。

スクリプトファイルを作成する

比較用に /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

結論

シェルスクリプト内でスクリプト自身のファイルパスを絶対パスを取得する場合、

  • シンボリックリンクを解決したパスが必要なら readlinkrealpath を使う。
  • シンボリックリンクを解決しないパスが必要なら cd + pwd を使う。