如何在bash中比较if条件中的两个字符串

San*_*yan 6 bash if-statement

s="STP=20"

if [[ "$x" == *"$s"* ]]
Run Code Online (Sandbox Code Playgroud)

if条件始终是假的; 为什么?

Fer*_*eak 6

试试这个:http : //tldp.org/LDP/abs/html/comparison-ops.html

string comparison

=

  is equal to

  if [ "$a" = "$b" ]
Run Code Online (Sandbox Code Playgroud)


Dav*_* W. 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
Run Code Online (Sandbox Code Playgroud)

注意区别:

$ 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
Run Code Online (Sandbox Code Playgroud)

但是,[ $f00 = *ar ]语法中有一些陷阱.这与:

test $foo = *ar
Run Code Online (Sandbox Code Playgroud)

这意味着shell将在执行语句之前插入glob表达式和变量.如果$foo为空,则命令将等效于:

test = *ar  # or [ = *ar ]
Run Code Online (Sandbox Code Playgroud)

由于=不是有效的比较运算符test,您将收到如下错误:

bash: [: =: unary operator expected
Run Code Online (Sandbox Code Playgroud)

这意味着[期望在test联机帮助页中找到参数.

而且,如果我的目录中碰巧有一个文件bar,那么shell将替换*ar 为匹配该模式的所有文件(在本例中bar),因此命令将变为:

[ $foo = bar ]
Run Code Online (Sandbox Code Playgroud)

这是真的.

要解决各种问题[ ... ],您应该始终在参数周围加上引号.这将阻止shell插入globs并帮助处理没有值的变量:

[ "$foo" = "*ar" ]
Run Code Online (Sandbox Code Playgroud)

这将测试变量$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
Run Code Online (Sandbox Code Playgroud)

因此,最后,如果要测试字符串相等性,可以使用[ ... ]或者[[ ... ]],但必须引用参数.如果要进行glob模式匹配,则必须不使用引号,并使用[[ ... ]].