仅当它是JSON时才通过jq管道输出
我有以下 BASH 代码:
response=$( curl -Ls $endpoint )
if [ -n "$response" ]; then # nonempty
echo "$response" | jq .
fi
问题是有时响应可以是非空的,但不是 JSON(如果它不是 200)。
jq如果输出是有效的 JSON,是否可以通过管道传输输出?
以下工作:
echo $x | jq . 2>/dev/null || echo $x
测试:
> x='{"foo":123}'; echo $x | jq . 2>/dev/null || echo "Invalid: $x"
{
"foo": 123
}
> x='}'; echo $x | jq . 2>/dev/null || echo "Invalid: $x"
Invalid: }
但是,我对此感到不舒服。
回答
如果您想在将其提交到 之前测试响应类型jq,则可以测试Content-Type来自服务器响应的标头。
所以你想curl向你发送完整的响应头和正文curl -i。
这是它的一个实现:
#!/usr/bin/env sh
endpoint='https://worldtimeapi.org/api/timezone/Europe/Paris.json'
# Headers and body are delimited by an empty line, with CRLF as the line ending.
# See: RFC7230 HTTP/1.1 Message Syntax and Routing / section 3: Message Format
# https://tools.ietf.org/html/rfc7230#section-3
crlf="$(printf 'rn_')" # add trailing _ to prevent trailing newline trim
crlf="${crlf%_}" # remove trailing _
http_delim="$crlf$crlf" # RFC7230 section 3
full_http_response="$(curl --silent --include --url "$endpoint")"
http_headers="${full_http_response%$http_delim*}"
http_body="${full_http_response#*$http_delim}"
case $http_headers in
'HTTP/1.1 200 OK'*'Content-Type: application/json'*)
# Yes, response body is JSON, so process it with jq.
jq -n "$http_body"
;;
esac