如何在 Bash 的“if”语句中比较两个字符串变量?[复制]

How do I compare two string variables in an 'if' statement in Bash? [duplicate]

提问人:Mr Shoubs 提问时间:11/25/2010 最后编辑:Peter MortensenMr Shoubs 更新时间:2/15/2021 访问量:1438840

问:

我正在尝试让一个语句在 Bash 中工作(使用 Ubuntu):if

#!/bin/bash

s1="hi"
s2="hi"

if ["$s1" == "$s2"]
then
  echo match
fi

我尝试了各种形式的语句,使用带引号和不带引号,使用 和 ,但我仍然收到以下错误:if[["$s1" == "$s2"]]===-eq

[hi:找不到命令

我查看了各种网站和教程并复制了它们,但它不起作用 - 我做错了什么?

最后,我想说如果包含,那我该怎么做呢?$s1$s2

我只是解决了空间问题...... :/我怎么说包含

我试过了

if [[ "$s1" == "*$s2*" ]]

但它没有用。

bash if-statement 脚本

评论

0赞 tripleee 12/15/2015
参见 stackoverflow.com/questions/9581064/...

答:

190赞 unwind 11/25/2010 #1

您需要空格:

if [ "$s1" == "$s2" ]

评论

20赞 racl101 4/20/2012
只是想说确保在开头和结尾方括号和语句之间留出一个空格,否则它将不起作用。此外,这也有效:"$s1" == "$s2"if test "$s1" = "$s2"
5赞 pooria 4/2/2016
这一切都与空间有关:))
1赞 Coty Embry 10/13/2016
@racl101的第一条评论为我解决了这个问题。谢谢!!
8赞 Charles Duffy 1/28/2018
==不适用于 ash、dash 或其他地方的基线 POSIX 实现。请改用。test=
19赞 jzrk 11/25/2010 #2

我建议:

#!/bin/bash

s1="hi"
s2="hi"

if [ $s1 = $s2 ]
then
  echo match
fi

不带双引号,只有一个等于

评论

0赞 jzrk 11/25/2010
是的,这是真的,我错过了空间。使用“[ $s 1 = $s 2 ]”,它可以工作。
7赞 tripleee 2/6/2016
为什么要省略双引号?它们是可选的,但在这种有限的特定情况下是无害的,但在许多实际情况下,删除它们将是一个严重的错误。另请参阅 stackoverflow.com/questions/10067266/...
4赞 Charles Duffy 1/28/2018
尝试使用 和 ,您会发现省略双引号是一个严重的错误。s1='*'s2='*'
0赞 Badri Paudel 4/10/2022
无论引号如何,我都对 = 或 == 有相同的行为。我不确定这是否是特定于 shell 的,我在我的 mac OS 版本上使用 zsh:10.15.7 (19H15)
8赞 Mrki 11/25/2010 #3

我现在无法访问 Linux 盒子,但实际上是一个程序(和一个内置的 Bash),所以我认为您必须在第一个参数之间放置一个空格。[[

另请注意,字符串相等运算符似乎是单个 .=

评论

0赞 Prisoner 13 10/10/2017
符号 [ 曾经是指向 /bin/test 的链接(反之亦然)。在 ubuntu 16.04 上显然不再是这种情况;不知道更改发生在何时何地。
0赞 TonyG 9/11/2022
我相信 13 号囚犯是不正确的。'[' 等效于 Ubuntu v20 中的 'test',要求最后一个参数必须是 ']'。
5赞 mpapis 11/25/2010 #4

用:

#!/bin/bash

s1="hi"
s2="hi"

if [ "x$s1" == "x$s2" ]
then
  echo match
fi

在里面添加一个额外的字符串可以使其更安全。

您还可以对单行命令使用另一种表示法:

[ "x$s1" == "x$s2" ] && echo match

评论

4赞 mloskot 7/10/2013
“更安全”是什么意思?为了完整和清晰起见,解释任何此类限定条件是很重要的。
4赞 mpapis 7/10/2013
事实上,它并不更安全,现在我知道如果你不引用它会更安全,这样可以防止其中一个是空的语法错误
1156赞 moinudin 11/25/2010 #5

对于字符串相等性比较,请使用:

if [[ "$s1" == "$s2" ]]

对于字符串不等于比较,请使用:

if [[ "$s1" != "$s2" ]]

对于 包含 ,请使用:ab

if [[ $s1 == *"$s2"* ]]

(并确保在符号之间添加空格):

坏:

if [["$s1" == "$s2"]]

好:

if [[ "$s1" == "$s2" ]]

评论

4赞 Wok 2/13/2014
stackoverflow.com/a/229606/376454我不得不使用这个答案来比较变量和固定字符串。
3赞 László Papp 10/21/2014
IRC 上挑剔的家伙告诉我你应该使用 if [[ “$s 1” == “$s 2” ]] 或 case。
21赞 tripleee 8/12/2016
在第一种情况下,双等号是错误的。Bash 可以容忍它,但便携式变体是 .参见 Rahul's answerif [ "$s1" = "$s2" ]
4赞 Sangimed 6/15/2017
嗨,我想知道为什么这很糟糕 -> 如果 [“$s 1” == “$s 2”] 空格有什么意义?
38赞 Charles Duffy 1/28/2018
@Sangimed,是一个命令(实际上是命令的替代名称);如果运行 ,你会看到磁盘上实际上有一个可执行文件(即使 shell 可能会提供内置实现作为性能优化)。就像您必须在要打印的文件名之前的命令名称之间放置一个空格一样,您需要在命令名称及其第一个参数之后以及它传递的每个参数之间放置一个空格(如果调用为 而不是 ,它期望它的最后一个参数是 )。[testwhich [ls[[test]
13赞 qwerty 11/25/2010 #6
$ if [ "$s1" == "$s2" ]; then echo match; fi
match
$ test "s1" = "s2" ;echo match
match
$

评论

5赞 tripleee 2/6/2016
双等号在 Bash 中是可以容忍的,但在其他一些方言中是不允许的。对于可移植性,应首选单等号,如果仅针对 Bash,则双括号扩展在多功能性、健壮性和便利性方面将更胜一筹。[[
206赞 trejo08 1/29/2013 #7

您应该注意在“[”符号和双引号之间留一个空格,其中变量包含以下内容:

if [ "$s1" == "$s2" ]; then
#   ^     ^  ^     ^
   echo match
fi

s 显示您需要留下的空格。^

评论

7赞 The Humble Rat 4/24/2014
非常感谢您指出必要的空间。解决了我的问题。今天刚开始 bash,似乎很多时候空格会导致错误,即声明变量等。
6赞 Tor Klingberg 8/10/2017
包括和部件的奖励积分。; thenfi
2赞 Charles Duffy 1/28/2018
==不适用于 ash、dash 或其他地方的基线 POSIX 实现。请改用。test=
3赞 user2546460 2/20/2014 #8

对于具有纯 Bash 且没有 但非常丑陋的版本,请尝试:test

if ( exit "${s1/*$s2*/0}" )2>/dev/null
then
   echo match
fi

说明:在打开一个额外的子 shell。如果有匹配项,则以 0 退出,如果没有引起错误(丑陋)的匹配项,则尝试以 $s 1 退出。此错误被定向到 。( )/dev/null

评论

0赞 m3nda 4/19/2015
一点也不差。喜欢解释和 sed 正则表达式喜欢。我永远不需要以这种方式使用 subshell。据我所知,您可以使用 or $(命令) 获取输出。我相信你可以测试它,然后让它变得更好。command
3赞 gniourf_gniourf 6/17/2016
在包含 glob 的情况下,这很容易被打破:要解决此问题,您需要引用扩展:。但是还有其他一些无法修复的细微错误:例如,if 是 's: 的列表,将声明匹配项。所以我强烈建议不要使用这种方法!另一个错误:.从 bash 4.4 开始,也会垃圾邮件标准输出。s2$s2"${s1/*"$s2"*/0}"s10s1=000000; s2=some_other_stuffs1=--; s2=stuffs1=--help; s2=stuff
43赞 Abderrazak BOUADMA 11/27/2014 #9

我建议这个:

if [ "$a" = "$b" ]

注意左/右括号和变量之间的空格,以及包裹“=”号的空格。

另外,请注意脚本标头。是否使用不是一回事

#!/bin/bash

#!/bin/sh

这是来源

评论

1赞 tripleee 8/12/2016
点赞,但在阅读 ABS 时始终要小心。 链接到更权威的来源可能是首选。
0赞 Abderrazak BOUADMA 8/12/2016
感谢您的建议,当然更权威的来源更准确。
1赞 holms 4/13/2017
/bin/sh: 1: [: 缺少 ]
1赞 Charles Duffy 1/28/2018
@holms,当完全按照此处给出的方式使用时,OP 的代码不会发生这种情况。您需要显示您的确切使用情况。
7赞 MikeW 8/13/2015 #10

这与其说是答案,不如说是澄清!是的,线索在错误消息中:

[hi:找不到命令

这表明您的“hi”已连接到“[”。

与更传统的编程语言不同,在 Bash 中,“[”是一个命令,就像更明显的“ls”等一样 - 它不会仅仅因为它是一个符号而被特别对待,因此“[”和(替换的)“$s 1”在你的问题中紧挨着,被连接起来(对于 Bash 来说是正确的),然后它试图在该位置找到一个命令: [hi - Bash 不知道。

在 C 语言和其他一些语言中,“[”将被视为不同的“字符类”,并且与后面的“hi”不相交。

因此,您需要在开头“[”之后有一个空格。

29赞 does_it_matter 3/29/2016 #11

这个问题已经有很好的答案,但在这里似乎在使用单相等 () 和双等于 () 之间存在轻微的混淆===

if [ "$s1" == "$s2" ]

主要区别在于您使用的脚本语言。如果您使用的是 Bash,请包含在脚本的开头并将脚本另存为 .要执行,请使用 - 然后您必须使用 .#!/bin/bashfilename.bashbash filename.bash==

如果您使用的是 sh,则使用您的脚本并将其另存为 .要执行使用,则必须使用单个 .避免将它们混合在一起。#!/bin/shfilename.shsh filename.sh=

评论

7赞 Tom Fenech 7/15/2016
断言“你必须使用”是不正确的。Bash 同时支持 和 .此外,如果你在脚本的开头,你可以使它可执行并像这样运行它(不是说文件扩展名很重要)。=====#!/bin/bash./filename.bash
0赞 does_it_matter 7/19/2016
完美,我想我现在必须删除这个答案,但如果你解释为什么如果不使文件可执行并通过在文件名前添加 sh/bash 来运行,这将非常有帮助?
0赞 tripleee 8/12/2016
这是对shebang和文件名的意义感到困惑。如果您正确地将 or 作为脚本的第一行,则只需运行它,实际文件名可以完全任意。#!/bin/sh#!/bin/bash./filename
0赞 does_it_matter 8/13/2016
现在这越来越有趣了,即使你不添加任何shebang和任何扩展并使用“bash/sh文件名”执行它,无论你使用单等于还是双等于,它都能工作。还有一件事,如果你使相同的文件(没有shebang和任何扩展名)可执行,那么你可以像./filename一样执行它(无论单倍或双倍)。(在带有 bash 4.3.46 的 Arch linux 上尝试过)。
0赞 MikeW 9/23/2016
如果你通过运行“bash filename”来执行文件,那么你只是将'filename'作为参数传递给程序'bash'--这当然会导致bash运行它。但是,如果您设置了“filename”执行权限,并尝试通过例如“./filename”来运行它 - 那么您将依赖于当前命令 shell 的默认“执行”行为 - 这可能需要“#!(shell)“行,以便工作。
42赞 Mike Q 5/29/2018 #12

Bash 4+ 示例。注意:当单词包含空格等时,不使用引号会导致问题。始终在 Bash IMO 中引用。

以下是 Bash 4+ 的一些示例:

示例 1,检查字符串中的“yes”(不区分大小写):

if [[ "${str,,}" == *"yes"* ]] ;then

示例 2,检查字符串中的“yes”(不区分大小写):

if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

示例 3,检查字符串中的“yes”(区分大小写):

 if [[ "${str}" == *"yes"* ]] ;then

示例 4,检查字符串中的“yes”(区分大小写):

 if [[ "${str}" =~ "yes" ]] ;then

示例 5,完全匹配(区分大小写):

 if [[ "${str}" == "yes" ]] ;then

示例 6,完全匹配(不区分大小写):

 if [[ "${str,,}" == "yes" ]] ;then

示例 7,完全匹配:

 if [ "$a" = "$b" ] ;then

评论

2赞 KANJICODER 8/24/2018
很好的答案。打赌,如果它离榜首不远,它会得到更多的赞成票。