我正在编写一些脚本来测试 API。我对 JSON 响应以及请求的 HTTP 状态代码感兴趣。我确实想漂亮地打印 JSON 响应,以便于阅读。
我正在用来curl
执行请求,并想用python -m json.tool
它来漂亮地打印 json 结果。
卷曲有一个不错的选择-w
可用于显示有关请求的信息,例如%{http_code}
.不幸的是,该信息打印到标准输出并令人困惑python -m json.tool
。似乎无法将其配置为忽略尾随的非 json 数据。
当我做
curl \
'--silent' \
'--insecure' \
'-L' \
'-w' \
'\n%{http_code}\n' \
'--user' \
<REDACTED> \
'-X' \
'GET' \
'--' \
'https://somecompany.com/some_api_endpoint' \
| python -m json.tool
我明白了
$ bash call_api_endpoint_script.sh
Extra data: line 2 column 1 - line 3 column 1 (char 203 - 207)
Exit 1
有没有办法配置curl
将状态代码写入文件?手册页中的选项-w
似乎没有提到将此信息重定向到其他地方的可能性。
答案1
$ curl -s -k -w '%{stderr}%{http_code}\n%{stdout}\n' \
https://run.mocky.io/v3/0e98ba3e-335e-421b-b762-884d2bf613ba |\
tee /dev/stderr | jq -r '.name'
200
{
"name": "Grape"
}
Grape
标准错误 从此时起,-w, --write-out 输出将被写入标准错误。 (7.63.0 中添加)
标准输出 从此时起,-w, --write-out 输出将被写入标准输出。这是默认设置,但可用于在切换到 stderr 后切换回来。 (7.63.0 中添加)
答案2
我找到了解决此问题的方法,即-o
仅将内容重定向到临时文件,只在curl 的输出中保留状态代码。
然后我可以从中读取临时文件的内容python -m json.tool
并漂亮地打印它们。
例如,
content=$(mktemp)
curl \
...
-w \
'HTTP_STATUS_CODE: %{http_code}\n' \
...
-o \
"$content" \
-- \
'https://somecompany.com/some_api_endpoint'
<"$content" python -m json.tool
答案3
如果你使用jq
而不是python -m json.tool
,你会发现它解析 JSON,甚至带有尾随文本:
$ echo '{ "foo": "bar" } text' | ./jq
{
"foo": "bar"
}
parse error: Invalid literal at line 2, column 0
当然,如果您想忽略错误消息,可以将其重定向到/dev/null
.
另请注意,jq
如果您想在管道中使用其输出或将其重定向到文件,我认为您需要给它一个“过滤器”参数:
echo '{ "foo": "bar" } trailing text' | jq . > OUT.json
.
只是最简单的过滤器。它的意思是“获取输入并将其不变地产生为输出”。
答案4
而写出-w
只能转到stdout
输出,-o
可以重定向到任何文件。特别是,您可以将其定向到stderr
with -o /dev/stderr
。如果您现在切换到stderr
and stdout
(使用3>&1- 1>&2- 2>&3-
),您将能够看到您的 HTTP 返回代码(通过 stderr),同时将输出通过管道传输到所需的程序。
换句话说,大致如下:
curl ... -w 'HTTP_STATUS_CODE: %{http_code}\n' -o /dev/stderr ... | 3>&1- 1>&2- 2>&3- | python -m json.tool