Category:
Linux
Python スクリプトでは、
これによって、スクリプトの単体試験容易性を確保できる (単体試験用スクリプトから試験対象のスクリプトを import して関数単位の試験実施ができる) というメリットがありそうです。ぜひ、シェルスクリプトにもこの記法が欲しいですね。
bash ではスクリプトファイルのコールスタックが BASH_SOURCE 配列に格納されるので、これの配列長を見ることでコンテキストの判定をしてみます。
すなわち、BASH_SOURCE の配列長が 1 であれば、実行中のコードの記述されたスクリプトが直接起動されたと判断できそうです。
というわけで、実験してみます。2 つのファイルを用意します。
ファイル 1: lib_foo.sh (インポートされる側)
... と、ここまで書いておいてアレですが、シェルスクリプトの単体試験を行うことができるフレームワークとして shUnit2 なるものがあるそうです。フレームワーク自体もシェルスクリプトで書かれているという時点でハマりどころのありそうな香りがプンプンしますがちょっと楽しそうなので、今度触ってみようと思います。
追記(2012/06/18)
Web を検索してみると、
if __name__ == '__main__':という記述をしばしば見かけます。この if 段落内のコードは、
- スクリプトを直接起動した場合、実行される
- 他のスクリプトから import された場合は、実行されない
これによって、スクリプトの単体試験容易性を確保できる (単体試験用スクリプトから試験対象のスクリプトを import して関数単位の試験実施ができる) というメリットがありそうです。ぜひ、シェルスクリプトにもこの記法が欲しいですね。
bash ではスクリプトファイルのコールスタックが BASH_SOURCE 配列に格納されるので、これの配列長を見ることでコンテキストの判定をしてみます。
すなわち、BASH_SOURCE の配列長が 1 であれば、実行中のコードの記述されたスクリプトが直接起動されたと判断できそうです。
というわけで、実験してみます。2 つのファイルを用意します。
ファイル 1: lib_foo.sh (インポートされる側)
#!/bin/bashファイル 2: foo_caller.sh (インポートする側)
function foo() {
echo "foo! foo!"
}
[ ${#BASH_SOURCE[@]} = 1 ] && {
echo "foo: begin"
foo
echo "foo: end"
}
#!/bin/bashそれぞれ実行権限を与えて、コマンド実行してみると…
. ./lib_foo.sh
foo
$ ./lib_foo.shということで、foo_caller.sh では lib_foo.sh をインポートしつつ、foo 関数だけを実行することができました。
foo: begin
foo! foo!
foo: end
$ ./foo_caller.sh
foo! foo!
[ ${#BASH_SOURCE[@]} = 1 ] && { ... }の箇所は、お好みに応じて
if [ ${#BASH_SOURCE[@]} = 1 ]; thenなどでもよいですね。
# ...
fi
... と、ここまで書いておいてアレですが、シェルスクリプトの単体試験を行うことができるフレームワークとして shUnit2 なるものがあるそうです。
追記(2012/06/18)
Web を検索してみると、
[ "${BASH_SOURCE}" = "${0}" ]という条件で同じことを判別しようとしているサンプルがありますが、これはダメです (スクリプト内で自分自身を source したケースを考えてみると分かりますね)。
Comments