卷曲以输出HTTP状态代码?


797

我正在curlLinux的命令行上使用,以发出HTTP请求。响应主体被打印为标准输出,这很好,但是我无法从手册页中看到如何卷曲来从响应中打印HTTP状态代码(404、403等)。这可能吗?


对于我来说,我可以从手册中了解如何获取HTTP状态代码,但是选项-w不起作用。我已经将该错误报告给了Apple。
Nicolas Barbulesco,2015年

19
根据superuser.com/a/514798/190188-icurl -i https://www.example.com/
凌晨

为什么不只是这样curl -IL http://www.example.com | grep "^HTTP\/"
St3an

不要对未来的自我:您想要的答案可能是西里尔·大卫(目前在第4位)
WhiteHotLoveTiger

Answers:


525

如果 Web服务器能够响应HEAD请求(这将不会执行GET),那么这应该对您有用:

curl -I http://www.example.org

另外,要让cURL跟随重定向(3xx状态),请添加-L。


154
注意:curl -I执行HEAD HTTP请求,对于某些Web应用程序服务器和服务的HTTP状态代码的测试可能会出现问题
Jay Taylor

16
并仅获取状态编号,请将其发送给head -n 1|cut -d$' ' -f2
Benubird

33
不要忘了重定向卷曲的标准错误:curl -I http://www.example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2。如果重定向后需要最终状态,请添加-L来卷曲。
亚伦·布伦库什

1
仅执行HEAD请求后执行重定向可能会导致有趣的行为,具体取决于应用程序的编程方式。
Scott McIntyre

31
curl -I -X GET将发送GET请求,但给出相同的输出。
jiggy 2015年

835

显示HTTP状态代码的一种更具体的方法是:

curl -s -o /dev/null -w "%{http_code}" http://www.example.org/

在脚本中使用起来要容易得多,因为它不需要任何解析:-)

-I可以添加该参数以提高响应负载性能。该参数仅请求响应的状态/标题,而无需下载响应正文。

注意: %{http_code}在HTTP有效负载的第一行返回

即:

curl -s -o /dev/null -I -w "%{http_code}" http://www.example.org/

54
-w“%{http_code}”是显示状态代码的位。您可以在其中添加一两个新行以将代码与正文分开(-w“ \ n \ n%{http_code} \ n”)
Jeffrey Martinez 2014年

7
哇,这/dev/null东西甚至可以在我使用的Windows版本的curl中使用。
Uwe Keim

3
我相信这会下载整个文件,即使所有文件都位于/ dev / null,因此对于检查大型文件的状态代码也不理想。httping -c 1 -s -G -m发出GET并不会下载整个文件,尽管我意识到这个问题专门与curl有关。
RomanSt

40
仅供参考:-s=不显示下载进度,-o /dev/null=不显示正文,-w "%{http_code}"=退出后将HTTP响应代码写入stdout。
Ajedi32 '16

1
是否需要在“%{http_code}”周围加上引号?
哈坎·巴巴

216

如果要查看标题和结果,可以使用详细选项:

curl -v http://www.example.org
curl --verbose http://www.example.org

状态将显示在标题中。例如

< Date: Tue, 04 Nov 2014 19:12:59 GMT
< Content-Type: application/json; charset=utf-8
< Status: 422 Unprocessable Entity

26
用于指出详细标志的+1提供了更多详细信息。非常适合测试REST应用。
MrOodles

8
+1在执行POST请求时非常容易使用(curl -v --data“ ...”)
MegaTux 2014年

1
它甚至将它们拆分为两个不同的文件输出(http状态详细信息为stderr,响应正文为stdout)
Blauhirn

201

除了执行所有标头之外,您还可以执行以下操作来打印状态代码:

curl -i http://example.org

好处-i是它也可以使用-X POST


36
比接受的答案(执行HEAD请求)好得多。
neu242

10
也许明显,但-i确实与工作的任何 HTTP方法,不只是GETPOST... :)
MAC

3
最佳答案,因为它使curl既输出标头又输出主体,使其适合在脚本中使用时的大多数任务
Sarge Borsch

6
这是最好的答案,可以与-s(不显示进度表或错误消息)和-S(毕竟不显示错误消息)一起使用
乔纳森·哈特利

69

如果要捕获变量中的HTTP状态代码,但仍将内容重定向到STDOUT,则必须创建两个STDOUT。您可以使用进程替换>()命令替换$()来实现

首先,使用3为当前进程的STDOUT 创建文件描述符exec 3>&1

然后,用卷曲的-o选项,使用重定向命令替换响应内容到一个临时FIFO,然后将该命令替换内,输出重定向回你的当前进程STDOUT文件描述符3-o >(cat >&3)

全部放在一起bash 3.2.57(1)-release(的标准配置macOS):

# creates a new file descriptor 3 that redirects to 1 (STDOUT)
exec 3>&1 
# Run curl in a separate command, capturing output of -w "%{http_code}" into HTTP_STATUS
# and sending the content to this command's STDOUT with -o >(cat >&3)
HTTP_STATUS=$(curl -w "%{http_code}" -o >(cat >&3) 'http://example.com')

请注意,这无法/bin/sh按照SamK在下面的注释中指出的那样进行


5
那真是个肮脏的东西……我喜欢!
spyle

3
现在如何依次将输出重定向到另一个变量?
罗杰·菲耶耶

1
输出在中STDOUT,因此您应该能够像常规命令一样将命令的输出重定向到所需的任何位置。我还没有测试过。
Heath Borders

1
不适用于/ bin / sh。
SamK '18 -10-11

好的答案,如果您希望外壳的可移植性,也可以重定向到真实文件并稍后将其分类
akostadinov

32

重新定义curl输出:

curl -sw '%{http_code}' http://example.org

可以与任何请求类型一起使用。


-k(-不安全)将覆盖-s(静默)。
Ravichandra

16

状态码

[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200

全部归功于该GIST


11

这是一个痛苦的curl --fail局限。来自man curl

-f,--fail(HTTP)在服务器错误时静默失败(根本没有输出)

但是无法在标准输出中同时获取非零返回码响应主体。

根据pvandenberk的回答以及在SO上学到的另一个非常有用的技巧,这里有一个解决方法:

curl_with_error_code () {
    _curl_with_error_code "$@" | sed '$d'
}
_curl_with_error_code () {
    local curl_error_code http_code
    exec 17>&1
    http_code=$(curl --write-out '\n%{http_code}\n' "$@" | tee /dev/fd/17 | tail -n 1)
    curl_error_code=$?
    exec 17>&-
    if [ $curl_error_code -ne 0 ]; then
        return $curl_error_code
    fi
    if [ $http_code -ge 400 ] && [ $http_code -lt 600 ]; then
        echo "HTTP $http_code" >&2
        return 127
    fi
}

此函数的行为与完全相同curl,但是curl如果HTTP代码范围为[400,600 [。


同意,无法看到错误输出是非常方便的--fail的痛苦限制。如何在不看到错误输出的情况下诊断REST api故障?不幸的是,卷发维护者装袋机顽固地坚持不提供--fail-but-show-error。github.com/curl/curl/issues/1978
jamshid

如文档中所述,它不适用于401和407 HTTP代码:(
Logan Mzz

11

这将向url发送一个请求,仅获取响应的第一行,将其拆分为块,然后选择第二行。

它包含响应代码

curl -I http://example.org 2>/dev/null | head -n 1 | cut -d$' ' -f2

1
您能否解释一下此代码的作用以及它如何解决OP给出的问题?无法解释的代码对用户而言可能看起来不受信任并且很危险。
bwDraco

1
当然,我们向url发送一个请求,仅获取响应的第一行,将其拆分为块,然后选择第二行。它包含OP寻找的响应代码。
Filip Spiridonov 2015年

9

对于POST请求,以下工作:

curl -w 'RESP_CODE:%{response_code}' -s -X POST --data '{"asda":"asd"}' http://example.com --header "Content-Type:application/json"|grep -o  'RESP_CODE:[1-4][0-9][0-9]'

6

使用以下cURL命令并将其通过管道传递给grep,如下所示:

$ curl -I -s -L http://example.com/v3/get_list | grep“ HTTP / 1.1”

每个标志的作用如下:

  • -I:仅显示响应标题
  • -s:静音-不显示进度栏
  • -L:跟随Location:标题

这是指向HTTP状态代码的链接。

从命令行运行。该curl在静默模式下运行,跟随任何重定向,获取HTTP标头。grep将HTTP状态代码输出到标准输出。



4

这是一些正在使用的curl命令,该命令GET返回HTTP代码。

curl -so /dev/null -w '%{response_code}' http://www.example.org

请记住,下面的方法使用HEAD,速度更快,但是对于某些不符合Web规范的HTTP服务器可能无法很好地工作。

 curl -I http://www.example.org

至少在OS X上不起作用。
2016年

在OS X High Sierra 10.13.6上对我来说工作正常。
本·男爵

4

有关如何使用响应代码的示例。只有在地理数据库已更改(-z)和以下重定向(-L)的情况下,我才使用它重新下载它们:

url=http://example.com/file.gz
file=$(basename $url)

response=$(curl -L -s -o $file -z $file $url -w "%{http_code}")

case "$response" in
        200) do_something ;;
        301) do_something ;;
        304) printf "Received: HTTP $response (file unchanged) ==> $url\n" ;;
        404) printf "Received: HTTP $response (file not found) ==> $url\n" ;;
          *) printf "Received: HTTP $response ==> $url\n" ;;
esac

3

OP希望知道状态码。通常,在下载文件时,您还希望了解它的大小,因此我首先使用curl来显示状态代码和文件大小,然后关闭详细信息并将文件定向到我想要的位置和名称:

curl -R -s -S -w  "\nhttp: %{http_code} %{size_download}\n" -o /Users/myfiles/the_local_name.html http://archive.onweb.com/the_online_name.html

然后我等待卷发的完成

wait ${!}

在运行下一个命令之前。上面的代码在上面的许多命令的脚本中使用时,给出了很好的响应,例如:

http:200 42824

http:200 34728

http:200 35452

请注意,curl中的-o必须紧随文件的完整路径+文件名。这样,当您使用curl进行d / l处理时,便可以将文件保存为合理的名称结构。还要注意,-s和-S一起使输出静音,但确实显示错误。还请注意,-R尝试将文件时间戳设置为Web文件的时间戳。

我的答案基于@pvandenberk最初建议的内容,但除此之外,它实际上将文件保存在某处,而不仅仅是指向/ dev / null。


1

将输出内容拆分为stdout,将HTTP状态代码拆分为stderr

curl http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

如果stderr只需要HTTP状态代码,--silent则可以使用:

curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2

然后,可以通过将不需要的流重定向到来选择所需的流/dev/null

$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 1>/dev/null
200
$ (curl --silent http://www.example.org -o >(cat >&1) -w "%{http_code}" 1>&2) 2>/dev/null
<!doctype html>
...

请注意,为了使第二种重定向能够按预期运行,我们需要在子shell中运行curl命令。


1
需要bash流程替代。
Jaakko

@Bruno,我从superuser.com/revisions/1444693/2更改了示例,因为我认为/tmp/out /tmp/err如果并行运行这些文件可能会导致意外结果。
Jaakko
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.