シェル変数にnullが入る場合の対処方法 ( シェル変数に設定された文字数確認 )

1.概要

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

プログラミングをする場合はPythonを利用する場合が多いのですが、Pythonでプログラムを記述するよりもシェル・プログラミングは効率性が高いと考えています。その理由は、バグが非常に少ない枯れたユーティティを活用するので問題発生の可能性が低いためです。

Pythonでプログラムを作成するとテストコードを記述しても設計誤りや試験漏れが必ずあり、プログラムの修正が必要になります。シェル・プログラミングは実行速度の面でも処理の作成方法に依存しますが、Pythonプログラム以上の性能を発揮できると考えています。

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

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

2.詳細

シェル・プログラミングを実施すると、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}が空の場合は等しくなるので判断できます。

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

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.所見

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

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

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

このことが理由で、私は${#VAL}方式を活用するようになりました。

参考

[本ブログ内参照]
ubuntuのshellのdash、組込shell変数の利用でbashとの違い
viewとvi(vim)を利用したHEX dumpの表示と修正方法

コメント

過去30日間に良く読まれた記事

miniPCのBMAXでWindows11のsecure boot設定漏れでトラブル発生

Windows95/98のPCゲームをUbuntu/LinuxMintの最新PCで楽しむ方法 ( KVM / Wine / dosbox-x / midi )

LinuxMint/ubuntuにWine 11導入を試しました ( LinuxMint 21.3 / 22.3 ubuntu 22.04 / 26.04 Wine 11.0 / 11.6 / 11.8 / 11.13 )