问题
我必须将字符串“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”开始。