[: =: unary operator expected

シェルスクリプトで、「[: =: unary operator expected」というエラーメッセージがでたときの解決策を紹介します。

事の経緯

私が、そのエラーメッセージと遭遇したのは、ある文字Aがある文字Bと等しい場合という条件分岐を設定したときに発生しました。

文字の比較の場合、シェルスクリプトでは、以下のような構文になります。

構文説明
-n 文字列文字列の長さが0より大きい
-z 文字列文字列の長さが0である
文字列1=文字列22つの文字列が等しい
文字列1!=文字列22つの文字列が等しくない

私が実際にそのエラーメッセージに遭遇したシェルスクリプトです。

#!/bin/bash

grep -q "FINISH" log &&  judge="EXIST"
if [ $judge = "EXIST" ];then
    echo "OK"
fi

logというファイル内に「FINISH」という文字列を見つけたら変数judgeを文字列「EXIST」にしています。その後、変数judgeが文字列「FINISH」ならば「OK」を出力しています。

一見何も問題がなさそうですが、タイトルにもある通り「[: =: unary operator expected」というエラーメッセージが出力されました。

原因

原因は、もしlogというファイルに「FINISH」という文字列がない場合、変数judgeは、値が入らないため、比較できないという原因でした。「FINISH」という文字列がある場合は、正常に動きました。

比較する変数に値が入っていないと発生するエラーメッセージだということが分かりました。

解決方法

変数に値が入っていない場合を考慮して “”で変数を囲むとエラーになりません。

先ほどのシェルスクリプトだと

#!/bin/bash

grep -q "FINISH" log &&  judge="EXIST"
if [ "$judge" = "EXIST" ];then
    echo "OK"
fi

ということです。

まとめ

シェルスクリプトで”[: =: unary operator expected”のエラーメッセージが発生した場合、

比較する変数をダブルクォーテーション(””)で囲むこと。