1. 概要

このチュートリアルでは、「単項演算子が期待される」問題を見ていきます。これは、条件文の式を評価するときによく発生します。最初に、その原因について説明します。 次に、この問題の解決に役立ついくつかの解決策について説明します。

2. エラーの原因

まず、ユーザーが入力した数が1に等しいかどうかをテストするヘルパースクリプトを作成しましょう。

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ $num1 -eq 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi

スクリプトができたので、テストしてみましょう。

$ ./unity_check.sh
Enter the input: 5
Not equal to One !!

ここまでは順調ですね! ユーザーがinputを指定せずにEnterキーを押した場合もテストしてみましょう。

$ ./unity_check.sh
Enter the input:
./unity_check.sh: line 3: [: -eq: unary operator expected
Not equal to One !!

特に、スクリプトは失敗し、理由として「単項演算子が期待されます」が挙げられます。 さらに、スクリプトを debug して、根本的な原因を特定しましょう。

$ bash -xv ./unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
+ read -p 'Enter the input: ' num1
Enter the input:
if [ $num1 -eq 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi
+ '[' -eq 1 ']'
./unity_check.sh: line 3: [: -eq: unary operator expected
+ echo 'Not equal to One !!'
Not equal to One !!

デバッグ出力からわかるように、ifステートメントは次のように評価されます。

if [ -eq 1 ]

ここで、変数の値が空白であるため、比較式の左側が消えます。事実上、等価性チェック(eq)の引数は1つだけです。オペレーター。 eq 演算子は二項演算子であり、2つの引数が必要なため、Bashは「単項演算子が必要です」と文句を言います。

次のセクションでは、このエラーを処理するための可能な解決策を確認します。

3. 変数を引用することによるエラーの防止

シェルの展開中に発生する単語の分割を防ぐために、変数を二重引用符で囲むことができます。 先に進んで、元のスクリプトを変更しましょう。

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ "$num1" -eq 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi

ここ、 $num1をに変更しました 「$num1」。 それでは、テストケースを実行してみましょう。

$ ./unity_check.sh
Enter the input: 1
Number entered is 1

通常のシナリオで動作します。 空白の入力についてもう一度確認してみましょう。

$ ./unity_check.sh
Enter the input:
./unity_check.sh: line 3: [: : integer expression expected
Not equal to One !!

ここで、「整数式が必要です」という別のエラーが発生します。 スクリプトをデバッグしましょう:

$ bash -xv ./unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
+ read -p 'Enter the input: ' num1
Enter the input:
if [ "$num1" -eq 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi
+ '[' '' -eq 1 ']'
./unity_check.sh: line 3: [: : integer expression expected
+ echo 'Not equal to One !!'
Not equal to One !!

デバッグ出力からわかるように、ifステートメントは次のように評価されます。

if [ '' -eq 1 ]

そして、リンゴとオレンジを比較しています! eq演算子を使用して文字列値を比較しているため、このエラーが発生しました (”)。演算子eqは整数比較のみ。 文字列値の等価比較には、「=」演算子を使用する必要があります。 スクリプトを変更して、テストケースを実行してみましょう。

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ "$num1" = 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi
$ ./unity_check.sh
Enter the input: 3
Not equal to One !!
$ ./unity_check.sh
Enter the input: 1
Number entered is 1
$ ./unity_check.sh
Enter the input:
Not equal to One !!

すべてのテストケースで期待どおりに機能します。

4. ダブルブラケット構文を使用してエラーを防止する

Bashでダブルブラケットテストコンストラクト[[を使用して、条件式を評価できます。 特に、この構成はPOSIXに準拠しておらず、Bashシェルと他のいくつかのシェルでのみ使用できます。 したがって、他のLinuxシェル環境に移行すると、スクリプトの移植性が失われる可能性があります。

二重括弧構文では、Bashは単語分割を実行しません。 これにより、変数が定義されていない可能性がある場合の耐性が高まります。

スクリプトを変更してみましょう。

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [[ $num1 -eq 1 ]]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi

それでは、空白の入力に対してテストケースを実行してみましょう。

$ ./unity_check.sh
Enter the input:
Not equal to One !!

すごい! 期待どおりに動作します。

5. 変数が定義されていないケースの処理

前のセクションでは、「単項演算子が必要です」エラーを防ぐ方法を確認しました。 このセクションでは、スクリプト内で定義されていない変数のシナリオを明示的に処理する方法を確認します。

5.1. 変数へのデフォルト値の割り当て

変数が定義されていない場合は、変数にデフォルト値を割り当てることができます。

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ "${num:-1}" -eq 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi

ここで、 $ {num:-1}構文により、num変数の値が定義されていない場合は1と見なされます。 さらに、いくつかのテストケースを実行して検証しましょう。

$ ./unity_check.sh
Enter the input: 4
Not equal to One !!
$ ./unity_check.sh
Enter the input:
Number entered is 1

5.2. -z単項演算子の使用

-z 演算子を使用して、空の文字列をテストすることもできます。

$ cat unity_check.sh
#! /bin/bash
read -p "Enter the input: " num1
if [ -z "$num1" ]
then
    echo "The number is empty"
    exit 0
fi
if [ "${num1}" -eq 1 ]
then
   echo "Number entered is 1"
else
   echo "Not equal to One !!"
fi

ここで、変数の値が空の場合、関連するステートメントを出力してスクリプトを終了します。

$ ./unity_check.sh
Enter the input:
The number is empty

6. 結論

このチュートリアルでは、「単項演算子が必要です」エラーに対処するための複数の手法について説明しました。

まず、このエラーの原因について説明しました。 次に、問題を防ぐために利用できるさまざまな解決策を学びました。

最後に、シェルスクリプトで定義されていない変数のケースを明示的に処理するためのいくつかのアプローチを確認しました。