私がシェルスクリプトを書いていたとき、 bash が勝手に環境変数を変えてくるという謎の挙動をした。なぜなのか調べた。
どんなことが起こったのか
私が書いていたシェルスクリプトは複雑で本題とは関係ない。話を簡単にするために、次のシェルスクリプト hello を書いていたとしよう。
環境変数 NAME
へ挨拶するスクリプトだ。
#!/bin/bash echo "hello, $NAME"
そして次のように実行した。すると意図しない挙動をする。
$ NAME=alice ./hello hello, bob
環境変数 NAME
は alice だったはず!
なぜ bash は環境変数を勝手に変えてくるのだろうか。
状況はどうであったか
このシェルの環境変数を見てみると怪しいものがある。
$ printenv ... BASH_ENV=/path/to/name ....
そして気になる /path/to/name の中身は次の通り。
NAME=bob
BASH_ENV とは
BASH_ENV
If this variable is set when Bash is invoked to execute a shell script, its value is expanded and used as the name of a startup file to read before executing the script.
環境変数 BASH_ENV
がセットしていたとき、bash スクリプトが実行されると、スクリプトが実行される前にファイル BASH_ENV
が読まれるそうだ。
つまり、上の name スクリプトは /path/to/name によって環境変数 NAME
が上書きされてしまったのである。
BASH_ENV を unset したら意図した挙動になった。
$ unset BASH_ENV $ NAME=alice ./hello hello, alice
なぜ BASH_ENV がセットされていたのか
ある GitHub リポジトリにあった Dockerfile で BASH_ENV
が使われていたのをよくわからずにコピペして動かしていたから。よくわからないものをコピペして動かすのはよくないね。