Curl返回http状态代码和响应

ran*_*ing 65 shell curl

我使用curl来获取http标头以查找http状态代码并返回响应.我用命令获取http标头

curl -I http://localhost
Run Code Online (Sandbox Code Playgroud)

为了得到响应,我使用命令

curl http://localhost
Run Code Online (Sandbox Code Playgroud)

一旦使用-I标志,我只得到标题,响应不再存在.有没有办法在一个命令中同时获取http响应和headers/http状态代码?

ran*_*ing 68

我能够通过查看指定使用的curl doc获得解决方案 - 输出将输出输出到stdout.

curl -o - http://localhost
Run Code Online (Sandbox Code Playgroud)

为了获得只有http返回码的响应,我可以做到

curl -o /dev/null -s -w "%{http_code}\n" http://localhost
Run Code Online (Sandbox Code Playgroud)

  • 或者你使用`-i`.或者也许是`-v`,如果你也喜欢一些额外的信息. (6认同)
  • 谢谢@DanielStenberg.接受的答案对我不起作用,只需使用-i就可以了. (2认同)
  • `-o -I`最终在CWD中创建一个名为字面'-I`'的文件.有没有人看到这个?解决方法是`-o/dev/null -I` (2认同)

scr*_*cer 24

我使用此命令打印状态代码而没有任何其他输出.此外,它只会执行HEAD请求并遵循重定向(分别-I-L).

curl -o -I -L -s -w "%{http_code}" http://localhost
Run Code Online (Sandbox Code Playgroud)

这使得检查运行状况脚本中的状态代码变得非常容易:

sh -c '[ $(curl -o -I -L -s -w "%{http_code}" http://localhost) -eq 200 ]'
Run Code Online (Sandbox Code Playgroud)

  • @MaciejJureczko - 价值很简单.出于脚本目的,这个答案是所有其他答案中最好的,因为它提供了单个状态代码,而不是多行垃圾以及所述状态代码. (7认同)
  • 这已在一年前得到解答.你的答案带来了什么新的价值?另外,请为您的答案写一些解释. (5认同)
  • 每当我使用这个 `curl -o -I -L -s -w "%{http_code}" http://localhost` 时,都会创建一个名为 `-I` 的文件,为了解决这个问题,我添加了一个文件输出的位置由 `-o` 暗示,即 `/dev/null`: `curl -o /dev/null -I -L -s -w "%{http_code}" http://localhost` (3认同)
  • 不过,HEAD 并不总是会产生与请求相同的输出,这取决于服务器如何响应。所以这并不是一个真正的答案。 (3认同)
  • 但是OP明确指出,他们都希望状态代码和响应正文都**。他们知道如何获取响应代码(问题中所述) (2认同)

Sco*_*oda 24

详细模式会告诉你一切

curl -v http://localhost
Run Code Online (Sandbox Code Playgroud)

  • 如果响应也有有效负载,则对我不起作用(在我的情况下,发送的状态代码未打印出来是 503) (2认同)

Tec*_*kie 15

这个命令

 curl http://localhost -w ", %{http_code}"
Run Code Online (Sandbox Code Playgroud)

将获得逗号分隔的正文和状态;你可以把它们分开把它们弄出来。

您可以根据需要更改分隔符。

  • 好提示!是否可以在输出前面添加状态代码? (4认同)

use*_*864 12

我用过这个:

    request_cmd="$(curl -i -o - --silent -X GET --header 'Accept: application/json' --header 'Authorization: _your_auth_code==' 'https://example.com')"
Run Code Online (Sandbox Code Playgroud)

获取HTTP状态

    http_status=$(echo "$request_cmd" | grep HTTP |  awk '{print $2}')
    echo $http_status
Run Code Online (Sandbox Code Playgroud)

为了获得响应主体,我已经使用了这个

    output_response=$(echo "$request_cmd" | grep body)
    echo $output_response
Run Code Online (Sandbox Code Playgroud)


Huy*_*ran 12

这是一种检索主体“AND”状态代码并将其格式化为适当的 json 或任何适合您的格式的方法。有些人可能会争辩说这是写入格式选项的不正确使用,但是当我需要脚本中的正文和状态代码来检查状态代码并从服务器中继响应时,这对我有用。

curl -X GET -w "%{stderr}{\"status\": \"%{http_code}\", \"body\":\"%{stdout}\"}"  -s -o - “https://github.com” 2>&1
Run Code Online (Sandbox Code Playgroud)

运行上面的代码,你应该得到一个这种格式的json:

{
"status" : <status code>,
"body" : <body of response>
}
Run Code Online (Sandbox Code Playgroud)

使用 -w write format 选项,由于首先打印 stderr,因此您可以使用 var http_code 格式化输出并将响应的正文放在一个值(正文)中,然后使用 var stdout 跟踪封闭。然后将您的 stderr 输出重定向到 stdout,您将能够将 http_code 和响应正文组合成一个整洁的输出

  • 出现以下错误 - ```curl:未知 --write-out 变量:'stderr'``` 和 ```curl:未知 --write-out 变量:'stdout'``` (5认同)

hid*_*pha 10

我实现这一目标的方法

为了获得两者(标题和正文),我通常执行curl -D- <url>以下操作:

$ curl -D- http://localhost:1234/foo
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 20:59:21 GMT

{"data":["out.csv"]}
Run Code Online (Sandbox Code Playgroud)

这会将 headers ( -D) 转储到 stdout ( ) (在man curl-中查找)。--dump-header

恕我直言,在这方面也非常方便:

我经常使用jq来获取格式化的 json 数据(例如,来自一些 REST API)。但由于 jq 不需要 HTTP 标头,因此技巧是使用-D/dev/stderr. 请注意,这次我们还使用-sS(--silent, --show-errors) 来抑制进度表(因为我们写入管道)。

$ curl -sSD/dev/stderr http://localhost:1231/foo | jq .
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:08:22 GMT

{
  "data": [
    "out.csv"
  ]
}
Run Code Online (Sandbox Code Playgroud)

我想如果您想将标题(用于快速检查)打印到控制台但将正文重定向到文件(例如,当它是某种二进制文件以免弄乱您的终端时),这也可以很方便:

$ curl -sSD/dev/stderr http://localhost:1231 > /dev/null
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:20:02 GMT

Run Code Online (Sandbox Code Playgroud)

请注意:这与 不一样curl -I <url>!As-I将执行HEAD请求而不是请求(在man curlGET中查找。是的:对于大多数 HTTP 服务器,这将产生相同的结果。但我知道很多业务应用程序根本不实现请求;-P--headHEAD


Edd*_*die 9

我发现了这个问题,因为我想同时提供响应和内容,以便为用户添加一些错误处理。

您可以打印HTTP状态代码以将其输出并将其内容写入另一个文件。

curl -s -o response.txt -w "%{http_code}" http://example.com
Run Code Online (Sandbox Code Playgroud)

这使您可以使用逻辑来确定响应是否值得处理。

http_response=$(curl -s -o response.txt -w "%{http_code}" http://example.com)
if [ $http_response != "200" ]; then
    # handle error
else
    echo "Server returned:"
    cat response.txt    
fi
Run Code Online (Sandbox Code Playgroud)


Aid*_*din 8

一行,只是为了获取状态代码将是:

curl -s -i https://www.google.com | head -1
Run Code Online (Sandbox Code Playgroud)

将其更改为head -2也会给出时间。


如果你想要一个 while-true 循环,它会是:

URL="https://www.google.com"

while true; do
    echo "------"
    curl -s -i $URL | head -2
    sleep 2;
done
Run Code Online (Sandbox Code Playgroud)

它将产生以下内容,直到您执行cmd+C(或ctrl+C在 Windows 中)。

------
HTTP/2 200
date: Sun, 07 Feb 2021 20:03:38 GMT
------
HTTP/2 200
date: Sun, 07 Feb 2021 20:03:41 GMT
------
HTTP/2 200
date: Sun, 07 Feb 2021 20:03:43 GMT
------
HTTP/2 200
date: Sun, 07 Feb 2021 20:03:45 GMT
------
HTTP/2 200
date: Sun, 07 Feb 2021 20:03:47 GMT
------
HTTP/2 200
date: Sun, 07 Feb 2021 20:03:49 GMT
Run Code Online (Sandbox Code Playgroud)


小智 8

使用管道可以清晰地读取

function cg(){
    curl -I --silent www.google.com | head -n 1 | awk -F' ' '{print $2}'
}
cg
# 200
Run Code Online (Sandbox Code Playgroud)

欢迎在这里使用我的 dotfile 脚本

解释

  • --silent: 使用管道时不显示进度条
  • head -n 1: 只显示第一行
  • -F' ':使用分隔符空间按列分隔文本
  • '{print $2}':显示第二列


Owe*_*ing 7

-i选项是您想要的选项:

curl -i http://localhost
Run Code Online (Sandbox Code Playgroud)

-i,--include在输出(H / F)中包括协议头

另外,您可以使用详细选项:

curl -v http://localhost
Run Code Online (Sandbox Code Playgroud)

-v,--verbose使操作更健谈


edi*_*999 5

对于编程用途,我使用以下内容:

curlwithcode() {
    code=0
    # Run curl in a separate command, capturing output of -w "%{http_code}" into statuscode
    # and sending the content to a file with -o >(cat >/tmp/curl_body)
    statuscode=$(curl -w "%{http_code}" \
        -o >(cat >/tmp/curl_body) \
        "$@"
    ) || code="$?"

    body="$(cat /tmp/curl_body)"
    echo "statuscode : $statuscode"
    echo "exitcode : $code"
    echo "body : $body"
}

curlwithcode https://api.github.com/users/tj
Run Code Online (Sandbox Code Playgroud)

它显示以下输出:

statuscode : 200
exitcode : 0
body : {
  "login": "tj",
  "id": 25254,
  ...
}
Run Code Online (Sandbox Code Playgroud)


jav*_*ett 5

这里有一些很好的答案,但就像我发现自己想要的OP一样,在脚本上下文中,所有:

  • 服务器返回的任何响应正文,无论响应状态代码如何:某些服务会在响应错误时以 JSON 形式发送错误详细信息
  • HTTP 响应代码
  • 退出curl状态代码

这很难通过一次curl调用来实现,我一直在寻找完整的解决方案/示例,因为所需的处理很复杂。

我将有关多路复用 stdout/stderr/return-code 的其他一些 bash 配方与此处的一些想法结合起来,得出以下示例:

{
  IFS= read -rd '' out
  IFS= read -rd '' http_code
  IFS= read -rd '' status
} < <({ out=$(curl -sSL -o /dev/stderr -w "%{http_code}" 'https://httpbin.org/json'); } 2>&1; printf '\0%s' "$out" "$?")
Run Code Online (Sandbox Code Playgroud)

然后可以在变量中找到结果:

echo out $out
echo http_code $http_code
echo status $status
Run Code Online (Sandbox Code Playgroud)

结果:

out { "slideshow": { "author": "Yours Truly", "date": "date of publication", "slides": [ { "title": "Wake up to WonderWidgets!", "type": "all" }, { "items": [ "Why <em>WonderWidgets</em> are great", "Who <em>buys</em> WonderWidgets" ], "title": "Overview", "type": "all" } ], "title": "Sample Slide Show" } }
http_code 200
status 0
Run Code Online (Sandbox Code Playgroud)

该脚本的工作原理是多路复用输出、HTTP 响应代码和curl由空字符分隔的退出状态,然后将它们读回到当前 shell/脚本中。curl可以使用返回 >=400 响应代码但也会生成输出的请求来测试它。

请注意,如果没有该-f标志,curl当服务器返回异常 HTTP 响应代码(即 >=400)时,不会返回非零错误代码,并且使用该-f标志,服务器输出会抑制错误,利用该标志进行错误检测且加工不具吸引力。

IFS 处理的通用学分read请参见以下答案: https: //unix.stackexchange.com/a/430182/45479


Nit*_*mar 5

获取响应代码和响应:

$ curl -kv https://www.example.org
Run Code Online (Sandbox Code Playgroud)

只获取响应代码:

$ curl -kv https://www.example.org 2>&1 | grep -i 'HTTP/1.1 ' | awk '{print $3}'| sed -e 's/^[ \t]*//'
Run Code Online (Sandbox Code Playgroud)
  • 2>&1:错误存储在输出中用于解析
  • grep:从输出中过滤响应代码行
  • awk:从响应代码行中过滤掉响应代码
  • sed:删除任何前导空格