如何在shell脚本中正确进行字符串比较?

3
我正在通过shell脚本执行我的URL并将响应存储在一个变量中。
http://hostname.domain.com:8080/beat

点击上述网址后,我将收到以下响应,需要对其进行解析并从中提取state的值。

num_retries_allowed: 3 count: 30 count_behind: 100 state: POST_INIT num_rounds: 60 hour_col: 2 day_col: 0

现在,我正在使用grep从上述字符串中提取状态变量的值。
#send the request, put response in variable
DATA=$(wget -O - -q -t 1 http://hostname.domain.com:8080/beat)

#grep $DATA for state
state=$(grep -oP 'state: \K\S+' <<< "$DATA")
[[ -z "$state" ]] && state=0

echo $state

如果在$DATA变量中没有包含state:字符串,那么我想将state变量赋值为0。然后我想验证条件并根据结果退出脚本。

如果state等于POST_INIT,则成功退出shell脚本;如果state等于0,也同样成功退出。

if [[ $state -eq "POST_INIT" || $state -eq "0" ]]; then exit 0; fi

所以我的上面的if条件不知何故没有起作用。我注意到如果我的 state 变量值为 IN_INIT,那么它也会退出 shell 脚本?在字符串比较方面,我在这里做错了什么吗?


"-eq" 用于数字。对于字符串,请使用“=”。 - Etan Reisner
@EtanReisner 感谢建议。是==还是= - john
POSIX 规范使用 =,但是如果你想使用 ==,bash 也可以接受(尽管我不建议这样做)。 - Etan Reisner
2个回答

2

-eq用于比较数字。=用于比较字符串。

如果你使用[而不是[[,你会因为一个值为POST_INITIN_INIT而得到一个错误。

$ state=POST_INIT
$ [ $state -eq 0 ]
-bash: [: POST_INIT: integer expression expected
$ echo $?
2

我认为[[的作用实际上更加聪明和令人烦恼。
我认为它扩展了变量,然后在算术上下文中使用扩展值(在此情况下,即使是裸词,变量也会被扩展),由于变量POST_INIT没有默认扩展为0的值,因此您的检查通过了。
$ state=POST_INIT
$ [[ $state -eq 0 ]]; echo $?
0
$ POST_INIT=5
$ [[ $state -eq 0 ]]; echo $?
1
$ POST_INIT=0
$ [[ $state -eq 0 ]]; echo $?
0

感谢详细的解释。我测试了这个 if [[ "$state" == "POST_INIT" || "$state" == "0" ]]; then exit 0; fi ,它运行得很好。您认为使用这个会有什么问题吗? - john
我认为看起来很好。对于一行代码,你可以选择使用[[ "$state" == "POST_INIT" || "$state" == "0" ]] && exit 0来减少一些混乱,但这只是风格上的问题,没有实际意义。 - Etan Reisner

0

正在尝试这个

 if [[ "$state" == "POST_INIT" || "$state" == "0" ]]; 

会有帮助,因为如果你使用类似 [ $state == "POST_INIT" ] 这样的语句,如果 $state 为空,它会忽略 $state 并且将该语句解析为 [ == "POST_INIT"。包括引号 " " 可以避免这种情况。


然而,当使用[[]]时,您无需引用变量。 if [[ $state == "POST_INIT" ... 将起作用。它们会自动引用,并且适用于多个单词和空字符串情况。 - Robin Hsu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接