s="STP=20"
if [[ "$x" == *"$s"* ]]
if
条件始终为false;为什么呢?
答案 0 :(得分:5)
[ ... ]
和[[ ... ]]
之间的平等测试存在差异。
[ ... ]
是test
命令的别名:
STRING1 = STRING2 字符串相等
但是,使用[[ ... ]]
当使用
==
和!=
运算符时,运算符右侧的字符串被视为模式,并根据模式匹配下面描述的规则进行匹配。如果启用了shell选项nocasematch,则执行匹配而不考虑字母字符的情况。如果字符串匹配(==
)或与模式不匹配(!=
),则返回值为0,否则返回1。可以引用模式的任何部分以强制它匹配为字符串。
只有=
符号才会出现同样的情况:
$ foo=bar
$ if [[ $foo = *ar ]]
> then
> echo "These patterns match"
> else
> echo "These two strings aren't equal"
> fi
These patterns match
注意区别:
$ foo=bar
> if [ $foo = *ar ]
> then
> echo "These patterns match"
> else
> echo "These two strings aren't equal"
> fi
These two strings aren't equal
但是,有一些[ $f00 = *ar ]
语法的陷阱。这与:
test $foo = *ar
这意味着shell将在执行语句之前插入glob表达式和变量。如果$foo
为空,则命令将等同于:
test = *ar # or [ = *ar ]
由于=
不是test
中的有效比较运算符,因此会出现如下错误:
bash: [: =: unary operator expected
这意味着[
期望在test
联机帮助页中找到参数。
而且,如果我的目录中碰巧有一个文件bar
,那么shell会将*ar
替换为与该模式匹配的所有文件(在本例中为bar
),因此命令将变为:
[ $foo = bar ]
这是真的。
要解决[ ... ]
的各种问题,您应该始终在参数周围加上引号。这将阻止shell插入globs并帮助处理没有值的变量:
[ "$foo" = "*ar" ]
这将测试变量$foo
是否等于字符串*ar
。即使$foo
为空,它也会起作用,因为引号将强制进行空字符串比较。 *ar
周围的引号将阻止shell插入glob。这是一个真正的平等。
当然,如果你在使用[[ ... ]]
时使用引号,你也会强制进行字符串匹配:
foo=bar
if [[ $foo == "*ar" ]]
then
echo "This is a pattern match"
else
echo "These strings don't match"
fi
因此,最后,如果要测试字符串相等性,可以使用[ ... ]
或[[ ... ]]
,但必须引用参数。如果要进行glob模式匹配,则必须不使用引号,并使用[[ ... ]]
。
答案 1 :(得分:3)
试试这个:http://tldp.org/LDP/abs/html/comparison-ops.html
string comparison
=
is equal to
if [ "$a" = "$b" ]
答案 2 :(得分:1)
要比较变量x
和y
中的两个字符串是否相等,请使用
if test "$x" = "$y"; then
printf '%s\n' "equal"
else
printf '%s\n' "not equal"
fi
要测试x
中是否显示y
,请使用
case $y in
(*"$x"*)
printf '%s\n' "$y contains $x"
;;
(*)
printf '%s\n' "$y does not contain $x"
;;
esac
请注意,这些构造可以移植到任何POSIX shell,而不仅仅是bash。测试的[[ ]]
构造不是(还)标准的shell特性。
答案 3 :(得分:0)
我不知道你在哪里提到*
,但你真的很亲密:
s="STP=20"
if [[ "STP=20" == "$s" ]]; then
echo "It worked!"
fi
答案 4 :(得分:-1)
您需要使用字符串=
中的\
转义s="STP=20"
s="STP\=20"
if [[ "STP\=20" == "$s" ]]; then echo Hi; else echo Bye; fi