変数に値が未セットの場合にのみ任意の文字を代入したい

bashシェルのスクリプトの中で特定の変数に値がセットされていない場合はデフォルト値を代入するということがあります。そこで、変数に値が未セットの場合にのみ特定の値をデフォルト値として代入することができます。

bashには様々な変数の参照方法があるんですが、${変数名:=値}と書くことで、値がセット済みの場合にはその値を返し、未セットの場合には任意の値を返すという動作をします。

1. インタラクティブなシェル上で変数を定義

例えば、$var変数にhelloという値を代入しておき、上記の書き方で値を参照してみます。

1
2
3
4
$ var="hello"

$ echo ${var:="goog morning"}
hello

$var変数を空にしてgoog morningという値を代入してみたいとしましょう。

1
2
3
4
5
6
7
$ var=

$ echo ${var:="goog morning"}
goog morning

$ echo $var
goog morning

${変数名:=値}という書き方をした場合、返り値としてセットした(あるいはセットされている)を返します。その返り値をechoでprintしています。

では、echoさせずに${変数名:=値}だけを実行するとどうでしょう。

1
2
3
4
5
6
7
$ var=

$ ${var:="goog morning"}
-bash: goog morning: コマンドが見つかりません

$ echo $var
goog morning

シェルは返り値をコマンドとして認識するのですが、goog morningなどというコマンドは存在しないのでメッセージが出力されます。しかし、$var変数への値のセットは成功したようです。

echoを使わずに、かつメッセージも出力させないためには以下のように、何もしないというコロン(:)を使う方法があります。

1
2
3
4
5
6
$ var=

$ : ${var:="goog morning"}

$ echo $var
goog morning

2. シェルスクリプト内の変数値にtrue/falseを使用する場合の注意点

シェルスクリプトでset -eを先頭に書いておくことで、スクリプト内のコマンドが失敗を返した場合にはスクリプトを終了させることが出来ます。おまじないのように書いていることがありますが、変数の値ににtrue/falseを使用している場合には注意が必要です。

truefalseはbashシェルの組み込みコマンドとして存在し、その名の通り、trueは真を返し、falseは偽を返します。なので、${var:=false}などと書いているとこの変数定義の行の実行結果は偽を返すことになります。

1
2
3
4
5
6
$ var=

$ ${var:="false"}

$ echo $?
1

シェルスクリプトでset -eとしている場合にはそこでスクリプトが終了してしまい、期待通りに動かない可能性があります。ここでも何もしないというコロン(:)を使用するという方法が有効です。