bashの振る舞いを変更するものに「シェル変数」がある。bashには、あらかじめ定義されているシェル変数と、ユーザーが設定することで振る舞いが変化する予約済みのシェル変数がある。


bashでは大文字小文字を区別するため、シェル変数名でも大文字と小文字は区別される。一般的な慣習として、bashが初期化、あるいは予約しているシェル変数名は大文字を使い、ユーザーが定義するシェル変数では小文字を使う。また、環境変数も一般的には大文字を使う。

簡単にいえば、ユーザーがシェル変数を使う場合には、小文字のみを使うことで、bashが予約するシェル変数やシステムが定義する環境変数との衝突を避けることができる。

今回は、bashの状態を示す、あるいは、設定することで振る舞いに影響する予約済みのシェル変数について解説する。まずは、シェル変数の基本的な部分を今回解説しておく。
シェル変数とは?

シェル変数とはプログラミング言語としてのbashの変数である。一般にプログラミング言語には変数と呼ばれる値を記憶する機能がある。シェル変数には、数値や文字列を記憶可能で、繰り返し同じ値を使う場合や、コマンドの実行結果を記憶させておく場合などに利用する。

シェル変数への記憶は以下の書式で行うことができる。

<変数名>=<値>

シェル変数には、値の形式を区別していないため、<値>は、数値でも文字列でも構わない。ただし、スペースを含む文字列は、シングルクオートあるいはダブルクオートでくくり、コマンドラインの区切り文字として認識されないようにする。


なお、シェル変数には、値が1つだけの「単純変数」のほかに、複数の要素を持つ「配列変数」、キーワードと値を対応させる「連想配列」(ハッシュテーブルともいう)の2つがある。これは配列を最初に定義するときの書式による決まる。

もう1つ、単純処理変数と同じ扱いができるものに「環境変数」がある。環境変数とシェル変数は、記憶される場所が異なるだけで、同じように扱うことができる。

シェル変数は、該当のbashセッション内のみで有効だが、環境変数は、すべての子プロセスからアクセスが行える。

シェル変数を環境変数にするには、exportコマンドを使う。原則bashでは、シェル変数を作成して、これを環境変数に変換することで環境変数を作成する。
シェル変数関連のコマンド

初期化されて値が設定されたシェル変数の一覧を得るには、setコマンドを使う。ただし、setコマンドは、そのままでは、シェル変数だけでなく、関数定義も出力する。これをシェル変数だけにするには、setコマンドを実行するbashをPOSIXモードで実行する。POSIXの定義では、setコマンドは、シェル変数のみを出力する。具体的には、サブシェルを使い

(set -o posix;set)

とする。
シェル変数名の一部から変数を検索したい場合には、後述のパラメーター展開を利用する。

環境変数の場合、printenvコマンドで環境変数の一覧を得ることができる。

配列変数や連想配列変数を定義するには、declareコマンド(あるいはtypesetコマンド)を利用する。配列変数は、

declare -a <配列変数名>=(値0␣値1␣値2……)

とするが、declare文を省略して「<配列変数名>[0]="abc"」だけでも配列変数を定義できる。なお、初期化時には、

<配列変数名>=(値0␣値1␣値2……)

とすることもできる。

連想配列の場合には、「-A」オプションを使い

declare -A <連想配列変数名>=([<キー1>]=値1␣[<キー2>]=値2␣[<キー3>]=値3……)

とする。同様に省略記法として

<連想配列変数名>=([<キー1>]=値1␣[<キー2>]=値2␣[<キー3>]=値3……)

として定義が可能だ。
パラメータ展開

シェル変数に記憶されている値を参照するには、bashのパラメータ展開(変数展開とも)を使う。パラメータ展開とは、

${<シェル変数名>}

と記述したものをシェル変数の値に置き換えるbashの機能だ。たとえば、引数を表示するechoコマンドなら

echo "${<シェル変数名>}"

とすることでシェル変数に記憶されている値を表示させることができる。なお、パラメータ展開を使う場合、bashの他の展開機能が適応されてしまわないように全体をダブルクオートでくくるべきだ。特にスクリプト内ではダブルクオートでくくることを心がけるようにすべきだ。


配列変数や連想配列変数の場合には、必ず波括弧の内側に添え字やキーを角括弧でくくって記述する。たとえば、

myArray=("abc" "def" "ghi" "jkl")
echo "${myArray[1]}"
myAssoc=(['a']=1 ['b']=2 ['shioda']=10)
echo "${myAssoc[shioda]}"

などとする(写真01)。

変数ではなくパラメータと呼ぶのは、スクリプトなどの引数を$1、$2などの「位置パラメータ」としてシェル変数のように扱うことも可能だからである。同様にパラメータには、記号文字を使う「特殊パラメータ」(表01)もある。

パラメータ展開には、さまざまな記法(表02)があり、変数からさまざまな情報を取り出すことができる。

実際に試してみるのが理解の早道である。分かりづらいのは、パラメーター展開で使われている「」と「@」の違いだろう。どちらもワイルドカード的に使われるが、対象が複数あるとき、「」は、展開した結果を標準の区切り文字(スペースまたは、シェル変数IFSの最初の文字)で連結した文字列を返す。これに対して「@」は、結果を配列で返す(写真02)。

ざっと駆け足でシェル変数(パラメータ)に関して解説を行った。次回は、bashが標準的に利用するシェル変数について見ていくことにする。

≫ Windows Subsystem for Linuxガイド 連載バックナンバー
https://news.mynavi.jp/tag/winsubsystem/
編集部おすすめ