卷曲以返回http状态代码以及响应


113

我使用curl获取http标头以查找http状态代码并返回响应。我通过命令获得了HTTP标头

curl -I http://localhost

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

curl http://localhost

一旦使用-I标志,我将仅获得标头,并且响应不再存在。有没有办法在一个命令中同时获取http响应和headers / http状态代码?


Answers:


111

通过查看curl文档,我可以找到一种解决方案,该文档指定-用于输出以将输出输出到stdout。

curl -o - http://localhost

要仅使用http返回代码获得响应,我可以这样做

curl -o /dev/null -s -w "%{http_code}\n" http://localhost

14
否则你会用-i。或者,-v如果您也喜欢一些其他信息。
丹尼尔·史登伯格

2
谢谢@DanielStenberg。接受的答案对我不起作用,仅使用-i即可。
亚历杭德罗·科蒂利亚

您的第二个命令丢失了-I @randominstanceOfLivingThing,除非有意将其作为空白选项?但是
如果

2
-o -I最终-I在CWD中创建了一个名为“ ” 的文件。还有其他人看到吗?解决方案是-o/dev/null -I
JDS

删除了-I。我注意到并纠正了。您不需要-I。
randominstanceOfLivingThing


36

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

curl -o -I -L -s -w "%{http_code}" http://localhost

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

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

5
一年前已经回答了。您的答案会带来什么新价值?另外,请为您的答案写一些解释。
Maciej Jureczko

11
@MaciejJureczko-值很简单。出于脚本目的,此答案是所有其他答案中最好的,因为它给出了一个状态码,而不是伴随着该状态码的多行垃圾。
aggregate116​​6877

2
但是OP明确声明他们需要状态码又需要响应主体。他们知道如何获取响应代码(在问题中已说明)
wottle

2
每当我使用此curl -o -I -L -s -w "%{http_code}" http://localhost文件时,都会创建一个名为的文件-I,以解决此问题,我为此添加了一个文件输出位置-o,即/dev/nullcurl -o /dev/null -I -L -s -w "%{http_code}" http://localhost
Thismatters

HEAD并不会始终与请求产生相同的输出,直到服务器如何响应为止。因此,这实际上不是答案。
艾迪

28

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

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

curl -s -o response.txt -w "%{http_code}" http://example.com

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

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

什么是http_code?我不明白,需要更多说明
亚历山大·米尔斯

以上阐明,它指的是HTTP状态代码- developer.mozilla.org/en-US/docs/Web/HTTP/Status
埃迪

22

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

curl -i http://localhost

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

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

curl -v http://localhost

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


16

我用了这个:

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

获取HTTP状态

    http_status=$(echo "$request_cmd" | grep HTTP |  awk '{print $2}')
    echo $http_status

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

    output_response=$(echo "$request_cmd" | grep body)
    echo $output_response

8

这个命令

 curl http://localhost -w ", %{http_code}"

将得到逗号分隔的正文和状态;您可以将其拆分以将其取出。

您可以根据需要更改定界符。


2
好提示!是否可以在输出前面添加状态代码?
Psychozoic

6

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

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

它显示以下输出:

statuscode : 200
exitcode : 0
body : {
  "login": "tj",
  "id": 25254,
  ...
}

5

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

curl -X GET -w "%{stderr}{\"status\": \"%{http_code}\", \"body\":\"%{stdout}\"}"  -s -o - https://github.com 2>&1

运行上面的代码,您应该以以下格式返回json:

{
"status" : <status code>,
"body" : <body of response>
}

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


1
得到了以下错误- curl: unknown --write-out variable: 'stderr'curl: unknown --write-out variable: 'stdout'
ALex_hha

curl.haxx.se/docs/manpage.html手册页显示了可用变量。不知道为什么stderr无法被您的卷曲识别,macbook上的卷曲即时识别。从这个Linux curl文档computerhope.com/unix/curl.htm中,我也没有将stderr视为变量。也许这是操作系统的变化。
惠特兰

我对此唯一的问题是,如果您的主体带有引号,例如其json,则主体将使json响应在无效json之上
theannouncer

@theannouncer足够公平,我希望开发人员能够相应地进行调整,因为并非所有响应都是标准json。由于回应的性质,我不得不调整某些情况。
惠特兰

2

我的实现方式

为了同时获得(标题和正文),我通常执行以下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"]}

这会将标头(-D)转储到标准输出(-)(--dump-headerman curl中查找)。

恕我直言,在这种情况下也非常方便:

我经常使用jq来格式化该json数据(例如,从其他Rest API中获取)。但是由于jq不希望使用HTTP标头,因此诀窍是使用将标头打印到stderr -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"
  ]
}

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

$ 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

请注意:这与curl -I <url>!不同。由于-I将执行HEAD请求,而不是GET请求(查找--head男子卷曲是:对于大多数HTTP服务器,这将产生相同的结果,但我知道有很多不实现业务应用程序。HEAD在所有;-P要求


-2
while : ; do curl -sL -w "%{http_code} %{url_effective}\\n" http://host -o /dev/null; done

1
你为什么要把它放在while循环中?请展开并解释您的答案。
Uberhumus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.