コード型ログ(5) Bashで自分のディレクトリを知る
シェルスクリプトで自分のディレクトリを知りたいことがあります。
. ./functions.sh
例えば、上のように他のシェルスクリプトを読み込みたいときに相対パスを使うのはよくないときがあります。なぜならば、./
の場所はシェルスクリプトを実行するカレントディレクトリであって、シェルスクリプトのファイルがある場所ではないからです。シェルスクリプトは、どのディレクトリから実行しても動くようにしたいものです。
シェルスクリプトのファイルが存在するディレクトリを知るには以下のようにします。
MYNAME="${BASH_SOURCE:-$0}" MYDIR=$(cd -P -- $(dirname -- "${MYNAME}"); pwd)
${MYNAME}
には今のファイルの相対パスが入っています。
${BASH_SOURCE:-$0}
となっているのは、$0
にはBash以外では今のファイルの名が入るのですが、Bashだとsource
もしくは.
でファイルを呼んだ実行ファイルの名前が入るからです。Bashには今のファイル名を表す変数BASH_SOURCE
というのが定義されているので、BASH_SOURCE
が定義されている場合にはそれを使い、BASH_SOURCE
が定義されていない、つまりBash以外のシェルの場合は$0
を使います。
"${A:-a}"というのは変数A
が定義されているときは${A}
を返し、そうでないときはa
を返すという意味です。なお、:-
のセミコロンは省略して${A-a}
でも可能です。*1
${MYDIR}
には今のファイルのディレクトリの絶対パスが入っています。
dirname -- "${MYNAME}
でディレクトリ名を取得します。--
はファイル名が-
で始まっているような場合にコマンドラインオプションとしてみなされないようにするためです。慣例として--
以降の引数はオプションとしてみなされません。
しかし、このままでは相対パスかもしれません。なので、絶対パスが欲しいときには、$(cd -P -- ${RELATIVE_DIR}; pwd)
として、絶対パスに変化します。-P
は${RELATIVE_DIR}
にシンボリックリンクが含まれていたときにそれを解くオプションです。
. ${MYDIR}/functions.sh
とすれば、どこから実行ファイルを呼んでもfunctions.sh
を見つけることができます。
追記
上では、実行ファイルがシンボリックリンクとなっている場合は、実体のあるディレクトリは分からない。その場合には、
MYNAME=$(readlink -f "${BASH_SOURCE:-$0}")
とする。
*1:ややこしいので個人的には"${A:-a}"で統一してほしいです。