在这个bash curl请求示例中,如何处理请求失败。即如果所有服务器都使用JSON响应,则一切正常,并且我在周期结束时有JSON文件。但是,如果其中一个服务器没有响应JSON或者根本没有响应,我确实没有" /data.json"文件,甚至所有其他服务器都运行良好。如何捕获服务器失败并跳过它?
#!/bin/bash
CONFIG=config.json
jsondata=data.json
i=1
echo "{ \"success\": \"OK\", \"servers\": {" > $jsondata
jq -r '.servers|keys[]' $CONFIG | while read key ; do
if [ "$i" -ne "1" ]; then
echo "," >> $jsondata
fi
echo "\"server$i\": {" >> $jsondata
RESPONSE=$(curl -s $HTTP://$IP:$PORT/api)
DATA1=$(echo $RESPONSE | jq '.data1')
DATA2=$(echo $RESPONSE | jq '.data2')
echo " \"data1\": $DATA1", >> $jsondata
echo " \"data2\": $DATA2", >> $jsondata
echo "}" >> $jsondata
((i++))
done
echo "}," >> $jsondata
答案 0 :(得分:1)
首先,我们假设我们有一个函数来进行单个API调用。
do_api () {
key=$1
curl $HTTP://$IP:$PORT/api # Presumably, key is needed here somewhere
}
我还假设预期的输出是一个JSON对象,其至少两个字段data1
和data2
。现在,我们可以编写一个包含三个阶段的简单管道:
$CONFIG
这不是太复杂:
jq -r '.servers | keys[]' | # stage 1
while read key; do do_api "$key"; done | # stage 2
jq -s 'to_entries |
map({key: "server(\.key+1)",
value: {data1: .value.data1,
data2: .value.data2}
}) |
{success: "OK", servers: from_entries}' # stage 3
do_api
不应为curl
的特定键输出任何内容,但如果您愿意,可以修改它以生成某种默认数据:
do_api () {
key=$1
curl --fail ... || jq -n '{data1: null, data2: null}'
}
jq -s 'to_entries'
接受
{ "data1": ..., "data2": ... }
{ "data1": ..., "data2": ... }
(这是我们对curl
的期望),并产生输出
[ { "key": 0, "value": { "data1": ..., "data2": ... } },
{ "key": 1, "value": { "data1": ..., "data2": ... } }
]
map(...)
过滤器获取前面的数组,并生成我们想要添加到最终结果中的servers
对象的键和值,这是通过调用from_entries
创建的。
这是一个完整的例子。 tmp.json
包含do_api
的模拟输出,以及将从最终输出中过滤的额外字段data3
。
$ cat tmp.json
{
"data1": "foo",
"data2": "bar",
"data3": "baz"
}
{
"data1": "hello",
"data2": "world",
"data3": "bye"
}
$ jq -s 'to_entries | map({key: "server\(.key+1)", value: {data1: .value.data1, data2: .value.data2}}) | {success: "OK", servers: from_entries}' tmp.json
{
"success": "OK",
"servers": {
"server1": {
"data1": "foo",
"data2": "bar"
},
"server2": {
"data1": "hello",
"data2": "world"
}
}
}