为什么我们不能比较。 (点)作为 if 语句的圆括号内的字符串值?

为什么我们不能比较。 (点)作为 if 语句的圆括号内的字符串值?

问题

我必须将字符串“problem1.sh”与其自身进行比较。它在以下情况下工作正常solution1.sh (如下所示)我使用方括号进行比较。但是,在以下情况下它不起作用solution2.sh (如下所示)我使用圆括号的地方。它显示了提到的错误(如下所示)

我已经尝试过什么?

我试图了解 bash 脚本中使用方括号和圆括号的区别这里这里。据我所知,它((expression))用于比较算术值,而不是字符串值。

那么,是什么造成了问题呢?

如果我从字符串“problem1.sh”中删除子字符串“.sh”并使用相同的语句进行比较if (("problem1" == "problem1")),则效果很好。然而,当我只添加“。”时在字符串中,它会产生问题。即使我删除了除“.”之外的所有内容。从字符串并使用语句if (("." == ".")),它显示错误。

然后,我的问题

如果声明if (("problem1" == "problem1"))可以正常工作(也许,它适用于英文字母表中的每个字母), 为什么 ”。”字符串产生问题?我的意思是,为什么我们不能比较“。”if (("." == "."))当我们可以使用相同的表达式(例如)比较字母时,在 bash 脚本的 if 语句中使用圆括号(例如if (("findError" == "findError")))?

解决方案1.sh

if [ "problem1.sh" == "problem1.sh" ]
then
        printf "Okay"   
fi

解决方案2.sh

if (( "problem1.sh" == "problem1.sh" ))
then
        printf "Okay"   
fi

Solution2.sh 的错误消息

./solution2.sh: line 1: ((: problem1.sh == problem1.sh : syntax error:
    invalid arithmetic operator (error token is ".sh == problem1.sh ")

答案1

语言翻译存在问题。
在算术表达式语言中,点不存在。

您使用的语言无法在“$((…))”内工作。

在“$((…))”(算术表达式)内只能有数字(通常是整数,如1234)、运算符 ( +-*<<yes==作为等式运算符等)和变量(一个或多个字母、数字(不是第一个字符)和下划线)。就这样。没有这个概念细绳

当您在算术表达式中写入时,problem1它在该语言中被理解为变量名(如果先前未定义,则值为 0):

$ echo "==$((problem1))=="
==0==

$ problem1=34
$ echo "==$((problem1))=="
==34==

文本是否在引号内并不重要:

$ echo "==$(("problem1"))=="
==34==

你正在使用什么,((…))也是一个算术表达式,它恰好没有输出。它只是设置退出状态(并且,如在 C 中一样,如果表达式的结果是不为 0)。

$ (( 1 + 1 ))  ; echo "$?"
0
$ (( 0 ))      ; echo "$?"
1
$ (( 1 - 10 )) ; echo "$?"
0

但是算术表达式不理解点是什么,既不作为运算符也不作为变量名,因此,它会生成语法错误:

$ echo "$(( 1.3 ))"
bash: 1.3 : syntax error: invalid arithmetic operator (error token is ".3 ")

这同样适用于变量名 ( problem1) 后跟一个点,然后再跟另一个变量名 ( sh)。

$ echo "$((problem1.sh))"
bash: problem1.sh: syntax error: invalid arithmetic operator (error token is ".sh")

如果运算符是 a+而不是点,则表达式将起作用:

$ echo "$((problem1+sh))"
34

如果problem1已设置为 34(如上)。

所以,唯一的比较方法字符串是使用[[…]]

$ [[ problem1.sh == problem1.sh ]] && echo YES
YES

(在这种特殊情况下,不引用 的右侧,==因为没有变量扩展并且字符串没有全局字符,但一般情况下,请引用 右侧的字符串==)。

或者,类似于您所写的:

if       [[ "problem1.sh" == "problem1.sh" ]]
then     printf "Okay"   
fi

答案2

正如您所怀疑的, (( == )) 比较两个数值。但在这些 (( )) 中,为了方便起见,您也可以只写变量名称 - 不必写 $VAR,只需写 VAR。

另请注意,错误消息不包含引号。我对此感到有点惊讶。实际上,不是——解析器检查它是否有替换,然后传递删除了引号的单词。

尽管如此,我相信解析器很乐意接受 Problem1 作为变量名,直到它遇到 .;所以它报告它无法理解的文本,从“.sh”开始。

相关内容