シェル変数にnullが入る場合の対処方法

記事の更新日:2026/09/30 評価を加筆、新しい手法を追加

1.概要

この記事は2023年の記事です。しかし、この記事は、私のシェル・プログラムのスタイルを変えた大切な記事だと思っています。もう一度、読み直し、リライトして備忘録に残すことにしました。

シェル・プログラミングに慣れてくるとVAR=$(pwd)などのように、コマンド実行結果をシェル変数に入れて処理の効率化をします。シェル・プログラミングは即時処理を実行できるので早く結果を出すには最速の方法だと思っています。

しかし、$(...)の実行結果がNULLになってしまいシェル変数の値をifで参照するとエラーとなります。シェル変数に入っている文字数を調べることが簡単にできることがわかり、シェル変数の値がNULLの対処方法をシェル変数に設定された文字数確認で実施できます。

以前はシェル変数に固定文字を付加して、結果が固定文字と同じであると、シェル変数の値はNULLだと判断する処理をしていました。シェル変数に設定された文字数確認のほうがスマートな気がします。

ネットで調べると新しいNullの調べ方が記載されていました。-z "$VAL"という手法がありました。その内容を追加記述します。

私の評価は以下の通りです。

(1) shellコードの読みやすさは、${#VAL}が優れています
(2) abc${VAL} != abcの比較も機能的に問題ありません
(3) shellコードは個人ユースの場合、他の方が見ることはありません
(4) 仕事でshellコードを書く場合は、${#VAL}を使うほうが良いと考えます
(5) -z "$VAL"は、更に新しい手法のようです。こちらも優れています

2.詳細

(1) abc${VAL} != abc を利用する手法

シェル・プログラミングを実施すると、VAL=$(...........)にて処理結果をシェル変数に入れます。しかし、シェル変数(ここでは${VAL})に値が設定できずにNULLとなると、
それ以降に記述するif文でエラーになります。

/dev/sddが存在しない環境で下記シェルを実行します。

VAL=$(lsblk | grep sdd)
if  [ ${VAL} = 1 ]; then
    echo "data is 1"
fi

上記事例の場合、${VAL}がNULLになるので、「unexpected operator(予期しない演算子)」という構文エラーになります。

これを回避するために、以前は下記のような記述をしていました。

VAL=$(lsblk | grep sdd)
if  [ abc${VAL} != abc ]  &&  [ ${VAL} = 1 ]; then
    echo "data is 1"
fi 

${VAL}が空の場合は等しくなるので判断できます。

(2) ${#VAL}を利用する手法

新しい記述方法は以下の通りで、シェル変数に設定された文字数を数えます。

echo ${VAL}は中身がなく、何も表示されません
VAL=""
echo ${VAL}

echo ${#VAL}は0となります
echo ${#VAL}
0

これでシェル変数に保存されている文字数を知ることができ、シェル変数の値がNULLの検知に利用しています。改良したシェルは以下の通りです。

VAL=$(lsblk | grep sdd)
if  [ ${#VAL} != 0 ]  &&  [ ${VAL} = 1 ]; then
    echo "data is 1"
fi 

(3) -z "$VAL"を利用する手法

進歩は著しいものです。更に新し標準手法が出ていました

VAL=$(lsblk | grep sdd)
if  [ ! -z "$VAL"  ]  &&  [ ${VAL} = 1 ]; then
    echo "data is 1"
fi 

この手法は変数をダブルクオートで括ることです。そして、-zでNullを確認できます。
こちらもスマートな方法です

3.所見

以前の方式でも可能ですが、新しい方式がスマートな感じです。また、処理内容が明確である点もスッキリしているとおもいます。私は新しい方式に順次入替えをしています。

以前の方式を最初にネットで見つけた時は、何を実行しているか、すぐに理解できませんでした。この記述方式はUbuntu/LinuxMintの中のシステムで利用するshellでも見かけることもあります。従って、以前の方式が誤りということではありません。

しかし、同じ文字列を等号の両端に追加してNullを見つけるやり方はスマートではありません。それよりも、シェル変数に保存された内容の文字数を数えてゼロであることを判別するほうがスマートだと思っています。

このことが理由で、私は${#VAL}方式を活用するようになりました。また、今回見つけた、
-z "$VAL"も少し様子を見ながら利用しようと思っています

参考

[本ブログ内参照]
・ubuntuのshellのdash、組込shell変数の利用でbashとの違い
・shell scriptを入れ子にした場合のteeの挙動について調べました

コメント