解决“Unary Operator Expected”错误
1. 概述
在本教程中,我们将研究**“Unary Operator Expected”问题,该问题在评估条件语句中的表达式时经常遇到。**首先,我们将讨论导致它的原因。然后,我们将讨论一些有助于我们解决此问题的解决方案。
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 !!
到目前为止,一切都很好!我们还测试用户在未指定输入的情况下按下回车键的情况:
$ ./unity_check.sh
Enter the input:
./unity_check.sh: line 3: [: -eq: unary operator expected
Not equal to One !!
值得注意的是,脚本失败了,原因是“Unary Operator Expected”。此外,让我们调试 脚本以确定根本原因:
$ 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)*运算符的参数。eq运算符是一个二元运算符,需要两个参数,因此,Bash 抱怨“预期的一元运算符”。
我们将在下一节中检查处理此错误的可能解决方案。
3. 通过引用变量来防止错误
我们可以对变量加双引号以防止在shell 扩展 期间发生单词拆分 。让我们继续修改我们的原始脚本:
$ 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 !!
**这里我们得到了一个不同的错误,“integer expression expected”。**让我们调试脚本:
$ 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 shell和其他一些 shell 中使用。因此,当迁移到其他 Linux shell 环境时,我们可能会失去脚本的可移植性。
在双括号语法中,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. 处理变量未定义的情况
在前面的部分中,我们检查了防止*“Unary Operator Expected”*错误的方法。在本节中,我们将检查在脚本中显式处理变量未定义场景的方法。
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