make と環境変数

Facebooktwittergoogle_plustumblrmail

シェル変数と環境変数

Unix 系の OS で一般に環境変数と呼ばれているものには、実は有効範囲の異なるものが 2 種類ある。
  • シェル変数 : そのシェルの中から実行される環境だけで有効な環境変数
  • 環境変数 : シェル変数の範囲に加え、そのサブシェルへも引き継がれる
シェル変数と環境変数の設定方法は、シェルによって異なる。
操作 sh 系 csh 系
シェル変数設定 VAR=VALUE set VAR VALUE
シェル変数削除 unset VAR unset VAR
シェル変数一覧表示 set set
環境変数設定 VAR=VALUE; export VAR or export VAR=VALUE setenv VAR VALUE
環境変数削除 unset VAR unsetenv VAR
環境変数一覧表示 printenv printenv
この表からも分かるように、 sh 系ではシェル変数をベースに公開指定 (export 指定) したものを環境変数と呼んでいるだけであるが、 csh 系ではシェル変数と環境変数が明確に区別されている。

コマンドライン実行と環境変数 (bash編)

まず、シェル変数を定義して見え方を調べてみる。 set はシェル変数を、 printenv は環境変数を表示する。だから、次の例では 4 行目の printenv 実行後に何も表示されない。 VAR1 を export して環境変数へ昇格すれば、 set からでも printenv からでも VAR1 が参照可能になる。
$ VAR1=VALUE1
$ set | grep VAR1
VAR1=VALUE1
$ printenv | grep VAR1
$ export VAR1
$ set | grep VAR1
VAR1=VALUE1
$ printenv | grep VAR1
VAR1=VALUE1
一時的な環境変数をコマンドに渡す実験。コマンドの手前に変数の定義を置くと、そのコマンド実行中にだけ有効な環境変数を定義できる。これは bash の機能である。しかし次の例では、 1 行目で set コマンドへ向けてこれを実行しても何も表示しない。ではこれを bash に頼らず env コマンドで実行するのが 2 行目の例だが、ここでエラーが発生する。実は、 set コマンドは bash の内部コマンドなので、 env が解釈できないのである。
$ VAR2=VALUE2 set | grep VAR2
$ env VAR4=VALUE4 set | grep VAR4
env: set: No such file or directory
従って、独立なコマンドである printenv を使えば、期待通りの結果を得る事ができる。 env を使わない場合 (1 行目) でも printenv が値を表示できている事から、これがシェル変数では無く、環境変数である事が分かる。
$ VAR3=VALUE3 printenv | grep VAR3
VAR3=VALUE3
$ env VAR4=VALUE4 printenv | grep VAR4
VAR4=VALUE4

NOTE : env コマンドは、引数を付けないと printenv コマンドと同じ動作になる。また、 env コマンドへオプション – (ハイフン) を付けると、明示的に指定した物以外の環境変数が消された状態でコマンドが走る。

シェル変数の有効範囲の実験。シェル変数はサブシェルへ継続されないので、 4 行目で起動したサブシェル内では set が何も表示しない (5 行目) 。サブシェルから元のシェルへ戻ってくれば、また復帰する (6 〜 8 行目) 。
$ VAR5=VALUE5
$ set | grep VAR5
VAR5=VALUE5
$ bash
$ set | grep VAR5
$ exit
$ set | grep VAR5
VAR5=VALUE5
一方、環境変数はサブシェルへも引き継がれる。
$ export VAR6=VALUE6
$ set | grep VAR6
VAR6=VALUE6
$ printenv | grep VAR6
VAR6=VALUE6
$ bash
$ set | grep VAR6
VAR6=VALUE6
$ printenv | grep VAR6
VAR6=VALUE6
$ exit
$ set | grep VAR6
VAR6=VALUE6
$ printenv | grep VAR6
VAR6=VALUE6

make と環境変数

以下の様な Makefile を用意する。暗黙定義の make 変数 CC と、自作した make 変数 DIR のふたつを用意し、 make のコマンドラインで指定する環境変数がこれら make 変数へ与える影響を見る事にする。
DIR=/tmp

all:
 @echo $(CC)
 @ls $(DIR)
make コマンドの手前に環境変数 CC 定義を置くと、 Makefile の中の make 変数 CC が上書きされる事が分かる (2 行目) 。
$ CC=Overwritten1 make
Overwritten1
CRX_75DAF8CB7768 kokubu pulse-2L9K88eMlGn7 ssh-nMPmZIIi1384
acroread_1000_1000 orbit-gdm pulse-CcctT9RwKSB1 sylpheed-1000
keyring-sdi1lH orbit-kokubu pulse-PKdhtXMmr18n
同様に env を使っても同じ結果が得られる (2 行目) 。
$ env CC=Overwritten2 make
Overwritten2
CRX_75DAF8CB7768 kokubu pulse-2L9K88eMlGn7 ssh-nMPmZIIi1384
acroread_1000_1000 orbit-gdm pulse-CcctT9RwKSB1 sylpheed-1000
keyring-sdi1lH orbit-kokubu pulse-PKdhtXMmr18n
make コマンドの引数として CC の定義を与えても同じ結果を得る。しかし、この挙動は環境変数とは無関係であり、単に make コマンド自体が持つ変数置換機能である (2 行目) 。
$ make CC=Overwritten3
Overwritten3
CRX_75DAF8CB7768 kokubu pulse-2L9K88eMlGn7 ssh-nMPmZIIi1384
acroread_1000_1000 orbit-gdm pulse-CcctT9RwKSB1 sylpheed-1000
keyring-sdi1lH orbit-kokubu pulse-PKdhtXMmr18n
次に Makefile の中へ自分で定義した make 変数 DIR を対象に同じ事を実験してみる。環境変数は DIR へ影響を与えられない (3 〜 5 行目、 9 〜 11 行目) 。
$ DIR=/var make
cc
CRX_75DAF8CB7768 kokubu pulse-2L9K88eMlGn7 ssh-nMPmZIIi1384
acroread_1000_1000 orbit-gdm pulse-CcctT9RwKSB1 sylpheed-1000
keyring-sdi1lH orbit-kokubu pulse-PKdhtXMmr18n
$
$ env DIR=/var make
cc
CRX_75DAF8CB7768 kokubu pulse-2L9K88eMlGn7 ssh-nMPmZIIi1384
acroread_1000_1000 orbit-gdm pulse-CcctT9RwKSB1 sylpheed-1000
keyring-sdi1lH orbit-kokubu pulse-PKdhtXMmr18n
しかし make コマンドの引数、つまり make コマンド自体の make 変数置換機能は利用可能である (2 行目) 。
$ make DIR=/var
cc
backups cache crash games lib local lock log mail opt run
spool tmp www
これまでの実験により、環境変数と make 変数、 make コマンドの挙動にはルールがある事が分かる。実は make コマンドが make 変数を置換する際に優先順位があり、それは以下の様になっている (優先順位が低い順) :
  1. 暗黙定義の make 変数
  2. make コマンド実行時の環境変数
  3. Makefile の中で明示的に値を代入している make 変数
  4. make コマンドの引数で置換指定した make 変数
また、この評価順序は make コマンドへオプション -e を与える事で一部変更可能だが、残念ながら行儀が悪い行為とされている (らしい) 。
Facebooktwittergoogle_plustumblrmail
Yusuke Dada K.
Yusuke Dada K.
台湾の現地企業で主に組み込みソフトウエアの研究開発をしている日本人です。我人是個日本人,負責軟體的研究開發。在臺灣的科技公司工作。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です