Help us understand the problem. What is going on with this article?

bash/zshでsourceされたスクリプト内で、ファイル自身の絶対パスをとるシンプルな記法

More than 5 years have passed since last update.
追記: コメント欄にて、若干変なパスが含まれている場合の対処方法について、補足いただきました。
ご指摘ありがとございますm(_ _)m

bash / zshなどでシェルスクリプトを書いていると、環境変数の設定を外部ファイルにまとめてsource して使う、というのはよくある。
そのような場合にsourceされたファイル内での絶対パスがイマイチうまく取れない、という問題に突き当たる事がある。

bashの話: うまくいかない方法と理由

通常、シェルスクリプト内で自分自身の絶対パスをとるときによくやるのが下記の手法だとおもう。

script_dir=$(cd $(dirname $0); pwd)

が、単体で呼び出した場合にはちゃんと動くのだが、bashからsourceで呼び出した場合にはうまく動かない。

なぜかというと、sourceされたファイルの実行が、呼び出し元のシェルプロセス内になるから。
bashでは$0は実行コンテキストに依らず、実行ファイル名が入っている。
そのため、source されたファイル内では$0が大本のファイルの情報となっているため、直感と異なる動きとなってしまう。

zshの話

ちなみに、zshだとちゃんと動く。zshは、$0をコンテキストに合わせて置き換える。
関数内であれば関数名になるし、sourceすればsourceされたファイルパスが入る。
そのため、zshなら$0を使っていれば問題ない。

bashの話: 解決の糸口

一般に言われるのは、$BASH_SOURCEを使う方法。
これには、呼び出されたファイル自身の絶対パスが入っている。そのため、bash限定であればこれを利用して

script_dir=$(cd $(dirname $BASH_SOURCE); pwd)

を使えば、解決できる。

これ使うと何が辛いか

bash限定なんですよね。zshかbashかを判定して、場合分けするような処理をいちいち書きたくない。

じゃあどうすんの

こうすればいい

script_dir=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)

$BASH_SOURCEが定義されていればそれを使い、無いなら$0を使う。
これでさくっと解決できる。

最後のほう書くの面倒になって説明が雑になった。。。わけじゃないよ!><

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした