Bashスクリプトで実行ファイルのディレクトリを取得する
よくやるのが以下の記述だったのだけれど
SCRIPT_DIR=$(cd $(dirname $0); pwd)
これだと、このスクリプトをシンボリックリンクから呼び出したときに、 実ファイルのパスでなくリンク先のディレクトリが取得されてしまっていた。 シンボリックリンクから呼び出されたときも、実ファイルのパスを返すようにするには、
SCRIPT_DIR=$(cd $(dirname $(readlink $0 || echo $0));pwd)
のようにすればよさげ。
追記)id:ngyukiさんにご指摘をいただいたので修正。
スクリプトがシンボリックリンクなディレクトリにあることを考慮して readlink -f とか cd -P とか pwd -P とかにするとなお良いのかな
おお、なるほど。やってみたら確かにシンボリックリンクなディレクトリにあるとうまくいかなかった。なので修正した以下の書き方がベターです。
SCRIPT_DIR=$(cd $(dirname $(readlink -f $0 || echo $0));pwd -P)
これならうまくいきました。
追記)2014-06-25
上記の記事はシンボリックリンクが相対パスだとやっぱりうまくいかなかったり、readlink -f
がmacでは使えなかったりでいろいろ至らない。
その後もいろいろ調べたら、rbenvのスクリプト内にあったabs_dirname
がいい感じでした。
ちょこっと手直ししたのが以下になります。
abs_dirname() { local cwd="$(pwd)" local path="$1" while [ -n "$path" ]; do cd "${path%/*}" local name="${path##*/}" path="$(readlink "$name" || true)" done pwd -P cd "$cwd" } script_dir="$(abs_dirname "$0")"