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

Let*_*rus 0 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
Run Code Online (Sandbox Code Playgroud)

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

显然,字符串比较失败。这是为什么?

mur*_*uru 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
Run Code Online (Sandbox Code Playgroud)

但是命令替换只会删除结尾的换行符(\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
Run Code Online (Sandbox Code Playgroud)

您可以尝试删除回车符:

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

然后:

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