2014年5月8日木曜日

bash でシェル変数が定義されているかを判定する方法は?

bash でシェル変数が(nullかどうかではなくて)定義されているかを判定したいと思って、調べたのですが、エレガントな方法がみつかりませんでした。

最初は、
if [ "${VAR:-UNDEF}" = "UNDEF" ] ; then
    ...
fi
だろうかと思ったのですが、VAR="" の時も真となってしまうので、微妙に違いました。それと、実際には無いはずとしても VAR="UNDEF" だったら、意図しない状況になってしまうのが引っかかります。処理内容によってはセキュリティホールのタネにもなるのではないか。

書籍調査/ネット検索の末に、
if ! set | grep -m 1 -q ^VAR= ; then
    ... # VARが未定義の場合に行う処理を記述
fi
とするしかなさそうなのですが、もっとエレガントな方法は無いものでしょうかね。現在のマシンでは大した処理コストではないですが、目的に対しては仰仰しいと思いました。
bash にそういった機能(isset のような)があったらいいように思いますが、需要がほとんどないし不要ということだろうか。

2014-05-10追記
匿名様(コメント参照)から情報頂き、
if [ -z "${VAR+x}" ] ; then    # VARが定義済み(nullを含む)の場合 x が返るので、-z でテストすれば OK
    ... # VARが未定義の場合に行う処理を記述
fi
と書けると知りました。少々難しい(慣れの問題?)ですが、手短に書けて良いでね。

2014-05-17追記
RHEL7.0 RC を調べていて、[ -v VAR ] が追加されているのを見つけました。
[root@hoge ~]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.0 (Maipo)
[root@hoge ~]# bash --version
GNU bash, バージョン 4.2.45(1)-release (x86_64-redhat-linux-gnu)
...
[root@hoge ~]# help test
...
    Other operators:
    
      -o OPTION      True if the shell option OPTION is enabled.
      -v VAR  True if the shell variable VAR is set
...
bash の CHANGES を確認してみると、バージョン 4.2 で追加されたようです。
------------------------------------------------------------------------------
This document details the changes between this version, bash-4.2-alpha,
and the previous version, bash-4.1-release.
...
3.  New Features in Bash
...
f.  test/[/[[ have a new -v variable unary operator, which returns success if
    `variable' has been set.
...
いちおう動作確認です。
[root@hoge ~]# VAR="set" ; [ -v VAR ] ; echo $?
0
[root@hoge ~]# unset VAR ; [ -v VAR ] ; echo $?
1
RHEL6/CentOS6 以下の bash では使えないので、当面は利用できないですが、メモまで。
人気ブログランキングへ にほんブログ村 IT技術ブログへ