为什么此字符串相等性测试失败?

时间:2019-05-16 06:17:59

标签: bash shell

美好的一天

我正在编写一个简单的脚本来测试Gitlab部署war文件后站点是否正常运行。

到目前为止,Bash脚本是:

#!/bin/bash

for i in {1..10}
    do
        response=$(curl -Is http://mysite/ | head -n 1)
        echo "$response"
        if [ "$response" == "HTTP/1.1 200 OK" ]; then
            echo "SITE UP"
            $i = 11
        fi
        sleep 5s
    done
if [ $i == 11 ]; then
    exit 1
fi
exit 0

echo "$response"echo "SITE UP"行仅用于故障诊断,将从最终脚本中删除。

这时我在终端上的输出是:

HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK

很明显,字符串比较失败。为什么会这样?

2 个答案:

答案 0 :(得分:10)

HTTP标头使用CRLF行尾(\r\n):

$ curl -Is http://example.com | head -n1 | od -c
0000000   H   T   T   P   /   1   .   1       2   0   0       O   K  \r
0000020  \n
0000021

但是命令替换仅去除尾随换行符(\n),而不去除回车符(\r),因此还有一个额外的字符:

$ response=$(curl -Is http://example.com/ | head -n 1)
$ printf "$response" | od -c
0000000   H   T   T   P   /   1   .   1       2   0   0       O   K  \r
0000020
$ printf "HTTP/1.1 200 OK" | od -c
0000000   H   T   T   P   /   1   .   1       2   0   0       O   K
0000017

您可以尝试删除回车符:

response=$(curl -Is http://mysite/ | head -n 1 | tr -d '\r')

然后:

$ response=$(curl -Is http://example.com/ | head -n 1 | tr -d '\r')
$ printf "$response" | od -c
0000000   H   T   T   P   /   1   .   1       2   0   0       O   K
0000017

答案 1 :(得分:1)

if命令实际上将命令作为参数,并评估其返回值。 if [ ... ]中的命令是[,它是test的别名。

如果您阅读the test manual page,将会发现您使用单个=来比较字符串。因此,您应该拥有

if [ "$response" = "HTTP/1.1 200 OK" ]; then

请注意,$response中的前后空格可能会导致字符串不相等。空格的示例包括换行符"\n"或回车符"\r"