当管道卷曲到 grep 时如何处理服务器关闭
how to handle server being down when piping curl to grep
我正在尝试编写一个脚本来查询 Web 服务器 API 并检查一个值,但我在尝试弄清楚如何最好地处理它时遇到了麻烦。到目前为止,我正在做的是使用 curl 获得响应,然后将其通过管道传递给 grep 以寻找模式。如果模式存在,我做一件事,如果不存在,我做另一件事。
if curl http://192.168.1.2:8080/api/query | grep -q mypattern; then
echo "success"
else echo "boo"
fi
但是如果服务器宕机,我不知道如何巧妙地处理它,因为服务器宕机产生的结果与找不到模式相同。我想要发生的是让 curl 继续发出请求,直到服务器响应,然后 grep 结果。我知道我可能会做到,但会非常笨拙。一个想法是首先循环 curl 直到退出代码为 0,但我确信有一种更实用的方法。有什么想法吗?
试试这个:
#!/bin/bash
n=5 # number of times to try.
testserver(){
read server mypattern <<<"$@" # read values of server and pattern
try=1 # lets start with try number 1.
while (( try++ < n )); do # have tried enough times?
test="$(curl --max-time 10 "$server" 2>/dev/null)"
(( $? == 0 )) && # If the connection was valid.
[[ "$test" =~ "$mypattern" ]] && echo "success" && break 1
sleep 5m # wait a little before trying again.
done
}
testserver "http://192.168.1.2:8080/api/query" "SomeStringToTest"
这看起来不太笨:
if while ! curl http://192.168.1.2:8080/api/query; do sleep 1; done |
grep -q mypattern; then
echo "success"
fi
您可能想限制调用 curl 的次数。你可以用类似的东西来做到这一点:
i=0; if while test $((i++)) -lt 4 && ! curl ...
可以使用 $PIPESTATUS
:
#!/bin/bash
if curl http://192.168.1.2/api/query | grep -q mypattern; then
echo "Found pattern"
elif [ "${PIPESTATUS[0]}" -eq 0 ]; then
echo "Server up"
else
echo "Server down"
fi
curl
具有内置超时状态,具有专用退出代码 (28)。
来自文档:
--connect-timeout <seconds>
Maximum time in seconds that you allow curl's connection to
take. This only limits the connection phase, so if curl con-
nects within the given period it will continue - if not it will
exit. Since version 7.32.0, this option accepts decimal values.
.....
28 Operation timeout. The specified time-out period was reached
according to the conditions.
所以你可以像这样编写主循环脚本:
#!/bin/bash
#mypattern.sh example
query=""
mypattern=""
dogrep () {
if (grep -q "$mypattern" /tmp/result);
then
echo "success"
else
echo "boo"
fi
}
curl -s --connect-timeout 5 "$query" -o /tmp/result
curlresult="$?"
case "$curlresult" in
"0") dogrep ; exit ;;
"28") echo "Could not connect to server" ; exit ;;
*) echo "something else went wrong" ; exit ;;
esac
</code> 是 API URL</li>
<li><code>
是模式
示例结果:
bash: >./mypattern.sh "http://google.com" "The document has moved"
success
bash: >./mypattern.sh "http://google.com" "The document has movde"
boo
bash: >./mypattern.sh "http://fjbdjhf" "The document has moved"
something else went wrong
bash: >./mypattern.sh "http://real.server.address.that.is.down" "The document has moved"
Could not connect to server
在上面:
- 示例1:连接成功,模式匹配成功
- 示例 2:连接成功,但没有模式匹配
- 示例 3:甚至不是真正的服务器,这是例外情况
- 示例4:真实服务器,但无法连接,5秒后超时
我相信如果您调整服务器停机的条件,这可以在某种程度上更符合您的特定要求。
- 在这个例子中:
“server being down”表示主机解析为真实地址,连接尝试在 5 秒内未被拒绝。
- 如果这是 Internet 上的 API 地址,那么对那里的 ISP 网关进行简单的 ping 检查以验证与 Internet 的一般连接性,再加上 5 秒超时将相当准确地覆盖服务器正在有效下降。
- 在您的情况下,在 LAN 上,您必须弄清楚什么确切条件意味着服务器已关闭,但此模板将各个部分分解得足以使很容易适应这些不同的因素。
while ! CURL_OUT="$(curl http://192.168.1.2:8080/api/query)"; do
sleep 5
done
if echo "$CURL_OUT" | grep -q mypattern ; then
echo "success"
else
echo "boo"
fi
我正在尝试编写一个脚本来查询 Web 服务器 API 并检查一个值,但我在尝试弄清楚如何最好地处理它时遇到了麻烦。到目前为止,我正在做的是使用 curl 获得响应,然后将其通过管道传递给 grep 以寻找模式。如果模式存在,我做一件事,如果不存在,我做另一件事。
if curl http://192.168.1.2:8080/api/query | grep -q mypattern; then
echo "success"
else echo "boo"
fi
但是如果服务器宕机,我不知道如何巧妙地处理它,因为服务器宕机产生的结果与找不到模式相同。我想要发生的是让 curl 继续发出请求,直到服务器响应,然后 grep 结果。我知道我可能会做到,但会非常笨拙。一个想法是首先循环 curl 直到退出代码为 0,但我确信有一种更实用的方法。有什么想法吗?
试试这个:
#!/bin/bash
n=5 # number of times to try.
testserver(){
read server mypattern <<<"$@" # read values of server and pattern
try=1 # lets start with try number 1.
while (( try++ < n )); do # have tried enough times?
test="$(curl --max-time 10 "$server" 2>/dev/null)"
(( $? == 0 )) && # If the connection was valid.
[[ "$test" =~ "$mypattern" ]] && echo "success" && break 1
sleep 5m # wait a little before trying again.
done
}
testserver "http://192.168.1.2:8080/api/query" "SomeStringToTest"
这看起来不太笨:
if while ! curl http://192.168.1.2:8080/api/query; do sleep 1; done |
grep -q mypattern; then
echo "success"
fi
您可能想限制调用 curl 的次数。你可以用类似的东西来做到这一点:
i=0; if while test $((i++)) -lt 4 && ! curl ...
可以使用 $PIPESTATUS
:
#!/bin/bash
if curl http://192.168.1.2/api/query | grep -q mypattern; then
echo "Found pattern"
elif [ "${PIPESTATUS[0]}" -eq 0 ]; then
echo "Server up"
else
echo "Server down"
fi
curl
具有内置超时状态,具有专用退出代码 (28)。
来自文档:
--connect-timeout <seconds> Maximum time in seconds that you allow curl's connection to take. This only limits the connection phase, so if curl con- nects within the given period it will continue - if not it will exit. Since version 7.32.0, this option accepts decimal values. ..... 28 Operation timeout. The specified time-out period was reached according to the conditions.
所以你可以像这样编写主循环脚本:
#!/bin/bash
#mypattern.sh example
query=""
mypattern=""
dogrep () {
if (grep -q "$mypattern" /tmp/result);
then
echo "success"
else
echo "boo"
fi
}
curl -s --connect-timeout 5 "$query" -o /tmp/result
curlresult="$?"
case "$curlresult" in
"0") dogrep ; exit ;;
"28") echo "Could not connect to server" ; exit ;;
*) echo "something else went wrong" ; exit ;;
esac
</code> 是 API URL</li> <li><code>
是模式
示例结果:
bash: >./mypattern.sh "http://google.com" "The document has moved"
success
bash: >./mypattern.sh "http://google.com" "The document has movde"
boo
bash: >./mypattern.sh "http://fjbdjhf" "The document has moved"
something else went wrong
bash: >./mypattern.sh "http://real.server.address.that.is.down" "The document has moved"
Could not connect to server
在上面:
- 示例1:连接成功,模式匹配成功
- 示例 2:连接成功,但没有模式匹配
- 示例 3:甚至不是真正的服务器,这是例外情况
- 示例4:真实服务器,但无法连接,5秒后超时
我相信如果您调整服务器停机的条件,这可以在某种程度上更符合您的特定要求。
- 在这个例子中:
“server being down”表示主机解析为真实地址,连接尝试在 5 秒内未被拒绝。
- 如果这是 Internet 上的 API 地址,那么对那里的 ISP 网关进行简单的 ping 检查以验证与 Internet 的一般连接性,再加上 5 秒超时将相当准确地覆盖服务器正在有效下降。
- 在您的情况下,在 LAN 上,您必须弄清楚什么确切条件意味着服务器已关闭,但此模板将各个部分分解得足以使很容易适应这些不同的因素。
while ! CURL_OUT="$(curl http://192.168.1.2:8080/api/query)"; do
sleep 5
done
if echo "$CURL_OUT" | grep -q mypattern ; then
echo "success"
else
echo "boo"
fi