コマンドやスクリプトを実行するときによく使われるコマンドの1つに、envコマンドがある。例えば、Pythonスクリプトの1行目に「#!/usr/bin/env python」と書いてあるのを見たことがあるかもしれない。

pythonコマンドは/usr/bin/pythonだったり、/usr/local/bin/pythonだったりと、デプロイされているディレクトリがディストリビューションごとに異なるケースがある。そのため、スクリプトの先頭に「#!/usr/bin/python」とか「#!/usr/local/bin/python」などと書いていると、環境を変えたら実行できなくなった……ということが起きる。

一方、envコマンドは/usr/bin/envにデプロイされていることが多い。そこで、envコマンドをpythonコマンドを呼び出すための「クッション」として利用しているのだ。これはenvコマンド本来の使い方とはちょっと違うのだが、便利なのでそうした用途にも使われている。今回は、このenvコマンドについて見ていこう。

指定したコマンドに対してのみ環境変数を変更する「env」

envコマンドは次のように引数を指定しないで実行すると、設定されている環境変数を一覧表示してくれる。

envコマンドを引数なしで実行(CentOSの場合)

envコマンドを引数なしで実行(macOSの場合)

envコマンドは引数に環境変数を指定することができ、さらにその後ろに指定したコマンドを実行してくれる。これが本来の使い方だ。例えば、calコマンドやdateコマンドは設定されているLANG環境変数の値に影響を受ける。次のような感じでenvコマンドを使ってやると、dateコマンドに関してだけ環境変数LANGの値を変更することができる。

指定したコマンドに対してのみ環境変数を変更できる

Bourne Shell系のシェルであれば「export LANG=jaJP.UTF-8」とか「export LANG=enUS.UTF-8」としても動作は同じになるが、この方法だとシェルそのものの環境変数が変更されてしまうので、ほかのコマンドにも影響を与えてしまう。envコマンドを使うと、そのときに指定したコマンドに対してのみ環境変数を変更できるのだ。

envコマンドは単純なコマンドなので基本的には「env 環境変数名=値 環境変数名=値 …… コマンド コマンド引数 ……」のように指定して実行するだけだが、いくつかオプションが用意されている。なかでも「-i」と「-u」は覚えておくとよいだろう。

「-i」は、環境変数を全てクリアするためのオプションだ。UNIX系OSでは環境変数の値がさまざまな動作に影響を与えるため、指定した環境変数だけに限定して実行したいことがある。-iオプションを指定した状態で、さらに必要な環境変数を指定すると、その環境変数だけの状態でコマンドを実行することができる。

-iオプションを指定すると環境変数をクリアすることができる

一方、-uオプションは指定した環境変数をアンセットするというものだ。設定されていると都合が悪い環境変数がある場合には、-uオプションを指定して明示的に設定を解除すればよい。例えば、次のように環境変数が設定されている場合を考えてみよう。

envコマンドを引数なしで実行(CentOSの場合)

-uオプションを指定して環境変数をアンセットすると、次のように定義されている環境変数が減っていることを確認できる。

-uオプションを指定して環境変数をアンセットする

最初に紹介した「#!/usr/bin/env python」というスクリプトの書き方では、envコマンドの本来目的としている機能は何も使っていない。環境変数の設定も変更もしておらず、ストレートにpythonコマンドを実行しているだけだ。なお、「#!/usr/bin/env -i LANG=ja_JP.UTF-8 HOME=/tmp python」のように記述して実行させることもできる。

デーモンのようなソフトウェアはいったん実行すると背後で動き続けるため、どういった状態で動作しているのかがよくわからなくなる。そうした場合、起動時にenvコマンドを経由して環境変数を明示的に指定するといった方法をとることがある。envコマンドはシェルスクリプトでも使用頻度が高いコマンドなので、ぜひ使い方を覚えてもらいたい。