curl 将 http 代码写入 stderr 或文件

curl 将 http 代码写入 stderr 或文件

我正在编写一些脚本来测试 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可以重定向到任何文件。特别是,您可以将其定向到stderrwith -o /dev/stderr。如果您现在切换到stderrand 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

相关内容