LoginSignup
0
0

More than 1 year has passed since last update.

シェルスクリプトのあるファイルの絶対パスをドットコマンドで読み込んだ場合も正しく取得する方法

Posted at

シェルスクリプト (bashスクリプト、zshスクリプト等) を書いた時、 そのファイルの絶対パス を取得するケースはよくあります。
例えば、そのシェルスクリプトから設定ファイルを読み込みたい場合などによく使います。

例えば、このようなスクリプトが scripts ディレクトリの中に run.sh という名前で作ってあって、

scripts/run.sh
#!/usr/bin/env zsh

. ./env.sh

(なにか処理...)

これを、

cd scripts
./run.sh

としても動作させる必要があり、 cd scripts しなくても

./scripts/run.sh

としても動作させたいのは、よくある要件でしょう。

その場合、定番として

scripts/run.sh
#!/usr/bin/env zsh

cd "$(dirname $0)" || exit

. ./env.sh

(なにか処理...)

$(dirname $0) と書きます。大抵はこれで十分なのですが、もしドットコマンドで読み込む設定ファイル env.sh の中でも同じことをやりたくて

scripts/env.sh
#!/usr/bin/env zsh

cd "$(dirname $0)" || exit

credentials_path=$(pwd)/credentials

とか

scripts/env.sh
#!/usr/bin/env zsh

credentials_path=$(dirname $0)/credentials

とやってしまうと、特定の状況でうまくいきません。

使用者は、

cd scripts
./run.sh

とか

./scripts/run.sh

とする以外にも、設定ファイルだけ読み込みたくて、他のディレクトリにあるファイルから

. ../scripts/env.sh

のように、設定ファイルを適用してしまう場合もあるためです。

検証

以下のファイルを作り、検証してみます。

scripts/run.sh
#!/usr/bin/env zsh

cd "$(dirname $0)" || exit

. ./env.sh
scripts/env.sh
#!/usr/bin/env zsh

echo "arg0: $0"
echo "PWD: $PWD"

cd scripts/; ./run.sh の場合

% ./run.sh
arg0: ./env.sh
PWD: /Users/ytyng/my-project/scripts

./scripts/run.sh の場合

% ./scripts/run.sh
arg0: ./env.sh
PWD: /Users/ytyng/my-project/scripts

上記2つはどちらも期待通りですが

./scripts/env.sh の場合

% ./scripts/run.sh
arg0: ./env.sh
PWD: /Users/ytyng/my-project/scripts

上記2つはどちらも期待通りですが

. ./scripts/env.sh

% . ./scripts/env.sh
arg0: ./scripts/env.sh
PWD: /Users/ytyng/my-project

env.sh を、他のディレクトリからドットコマンドで適用した場合、 $0 などの結果が最初の例と変わってしまいます。

シェルスクリプトの中で安定して現在のディレクトリを取得するには

scripts/env.sh
#!/usr/bin/env zsh

cd $(dirname $0) 2>/dev/null || cd ${PWD}
env_pwd=$(pwd)
cd -

少し強引ですが、上記のように dirname $0 が失敗したら ${PWD}cd すればうまくいくと思います。

応用

スクリプトのあるディレクトリの2つ上の /credentials ディレクトリを作る

cd $(dirname $0) 2>/dev/null || cd $PWD
credentials_dir=$(dirname $(dirname $(pwd)))/credentials
cd -
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0