![如何比较 bash 变量与双引号](https://linux22.com/image/136029/%E5%A6%82%E4%BD%95%E6%AF%94%E8%BE%83%20bash%20%E5%8F%98%E9%87%8F%E4%B8%8E%E5%8F%8C%E5%BC%95%E5%8F%B7.png)
我有这个代码
STATUS=`echo "test"`
if [ $STATUS == "test" ]; then
exit 0
fi
我已经尝试了一切,但我无法实现它。
我试过
"$STATUS" == "test"
eval $STATUS == "test"
${STATUS[@]} == "test"
唯一有效的是
$STATUS == \"test\"
答案1
问题中的代码有效,这意味着它将执行该exit 0
语句。
你的
STATUS=`echo "test"`
是相同的
STATUS="test"
和(在这种情况下)作为
STATUS=test
即变量STATUS
被指定test
为值(值中没有双引号)。
要针对该值进行测试test
,请执行以下操作
if [ "$STATUS" = "test" ]
或者
if [[ $STATUS == "test" ]]
如果STATUS
有值"test"
,如
STATUS='"test"'
然后在比较中使用该字符串:
if [ "$STATUS" = '"test"' ]
或者
if [[ $STATUS == '"test"' ]]
也可以看看:
答案2
中那些转义的引号\"test\"
让我认为 shell 的引用规则存在一些混乱,因为第一段代码按预期工作,但$STATUS == \"test\"
不应该(除非你写了STATUS=`echo '"test"'`
或类似的东西)。
为了正确澄清这种混乱,需要解释一些shell概念。
引用
在 POSIX shell 中,引用是最重要的机制之一。不幸的是,它也是一个非常令人困惑的主题,如果使用不当,它会成为脚本中错误和奇怪行为的重要来源。
基本规则如下:
- 转义字符
\
:保留后面的下一个字符的字面值,但 除外<newline>
。 - 双引号
"
:保留引号内所有字符的字面值,但 、$
和(启用历史扩展时)除外。`
\
!
- 单引号
'
:保留引号内所有字符的字面值,无一例外。
命令替换
命令替换允许命令的输出替换命令本身。它的语法是$(command)
or `command`
,尽管前者是首选。
测试命令
该命令(在 POSIX 以及bash、ksh 和 zsh 等 shell 中test
也称为该命令)可让您使用许多有用的条件和算术表达式。例如,它可以检查给定的常规文件是否存在并且可读、两个字符串是否相等或者一个数字是否大于另一个。[
[[
现在,分析一下代码:
STATUS=`echo "test"`
这里的命令替换是没有用的,因为它可以写成STATUS="test"
.请注意,双引号不是由 打印的echo
,因此STATUS
保留test
为其值。
if [ $STATUS == "test" ]; then
exit 0
fi
这里至少有 3 个潜在缺陷:
- 未引用的内容
$STATUS
可能会受到分词的影响。 ==
是非 POSIX 语法。=
如果您关心便携性,请使用。if
并且exit 0
在这种情况下毫无用处,因为它[
已经完成了预期的工作。
另请注意,与前一行代码一样,双引号不是按字面意思理解的,因此生成的命令(在扩展和删除引号之后)是[ test = test ]
,这是正确的。
但如果您的目标是具有"test"
的值STATUS
,那么
STATUS=\"test\"
STATUS="\"test\""
STATUS='"test"'
都是有效的作业并且
[ "$STATUS" = \"test\" ]
[ "$STATUS" = "\"test\"" ]
[ "$STATUS" = '"test"' ]
都是有效的条件表达式。
答案3
根据您使用的 shell,此问题的解决方案可能有所不同。另外,请确保 $STATUS 在与脚本中的“echo $STATUS”行进行比较之前包含“test”。检查变量的内容对于调试非常有帮助。虽然不太可能,但有很小的可能是其他程序正在设置它,在这种情况下它显然会失败。
一般来说,您编写的代码应该工作。如果不是,问题可能出在脚本中的任何其他代码、shell 本身或其他一些程序干扰上。您可以尝试使用导出在系统范围内导出变量,以确保其设置正确。这应该覆盖任何干扰值。请记住,如果另一个程序正在干扰,它可能不喜欢它的变量被更改。
作为参考,我将提供以下信息:
将变量设置为简单状态(例如“测试”)的最佳方法很简单:
VARIABLE="value"
虽然您可以使用 echo 将文本返回到变量中,但对于像 test 这样的字符串,没有理由这样做。除非您打算使用 echo -e 或 printf 插入控制字符(例如换行符)。
比较字符串的推荐方法是使用以下任一方法:
if [ "$VARIABLE" = "value" ]; then
if [[ $VARIABLE == value ]]; then
如果您还没有尝试过,请尝试使用较新的 [[,也称为扩展测试,而不是 [,也称为经典测试。
http://wiki.bash-hackers.org/commands/classictest
http://wiki.bash-hackers.org/syntax/ccmd/conditional_expression
如果您想了解有关测试操作员的所有详细信息,这些都是很好的资源,可以帮助您获取更多信息。