让 curl 输出 HTTP 状态码?
我在 Linux 上使用 curl
命令行发出 HTTP 请求。响应体被打印成标准输出,这很好,但我在man page上看不到如何让curl从响应中打印出HTTP状态码(404,403等)。这可能吗?
一个更具体的方法是打印出******的HTTP状态代码,如下所示:
curl -s -o /dev/null -w "%{http_code}" http://www.example.org/
在脚本中更容易操作,因为它不需要任何解析。这个参数只是请求响应的状态/页眉,而不是下载响应的正文。
如果你想看标题和结果,你可以使用以下选项:
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
除了所有的标题外,你还可以通过以下操作打印状态码:
curl -i http://example.org
``` &001
好在`-i`的好处是,它也可以和`-X POST`一起使用。
如果你想在一个变量中捕获HTTP状态码,但仍然将内容重定向到STDOUT,你必须创建两个STDOUT。你可以用process substitution >()和command substitution $()来完成。
然后,使用curl的3
选项,用命令替换将响应内容重定向到一个临时的fifo,然后在这个命令替换中,用exec 3>&1
重定向输出到当前进程的STDOUT文件描述符-o
。
在3
-o >(cat >&3)
中把它放在一起(bash
的标准):
# 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')
注意,这在3.2.57(1)-release
中不起作用,因为SamK在下面的注释中指出。
重新定义卷曲输出:
curl -sw '%{http_code}' http://example.org
&001
可用于任何请求类型。
状态代码 **只*
[0]$ curl -LI http://www.example.org -o /dev/null -w '%{http_code}\n' -s
[0]$ 200
所有的功劳都归于此 GIST
这是一个很痛苦的curl --fail
限制。来自man curl
:
-f, –fail (HTTP) 在服务器错误时无声无息地失败(完全没有输出)
但没有办法在stdout中同时得到非零返回码和响应体。根据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
完全一样,但是在HTTP代码在[400, 600[.
这将向url发送一个请求,只得到响应的第一行,在块上拆分,并选择第二行。
对于一个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]'
使用下面的cURL命令,并将其管到grep中,如:
$ curl -I -s -L http://example.com/v3/get\_list | grep “HTTP/1.1”
以下是每个标志的作用:
-I
: 只显示响应头-s
: Silent - 不显示进度条 -L
: 遵循Location:
头条 这里有一个链接到 HTTP状态码 . grep将把HTTP状态码打印成标准输出。
如何使用响应码的一个例子。我用这个来重新下载Geolite数据库,只有当它们发生了变化时才会重新下载(-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
OP想知道状态码。通常在下载文件的时候,你也想了解一下文件的大小,所以我先用curl显示状态码和文件的大小,然后关闭verbose,直接将文件引导到我想要的地方和名字:
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
然后等curl
wait ${!}
&001
完成后,再运行下一条命令。上面的命令在脚本中使用时,会给出一个很好的响应,比如:
http: 200 42824
http: 200 34728
http: 200 35452
请注意,curl中的-o需要在文件的完整路径+文件名后面加上文件的完整路径。这样,当你使用 curl 来保存文件时,就可以以合理的名称结构来保存文件。另外注意-s和-S一起使用会使输出沉默,但会显示错误。另外注意-R试图将文件的时间戳设置为网页文件的时间戳。
我的答案是基于 @pvandenberk 最初的建议,但它实际上是将文件保存在某个地方,而不是仅仅指向/dev/null。
将输出内容拆分到stdout
,将HTTP状态码拆分到stderr
:
curl http://www.example.org -o >(cat >&1) -w "%{http_code}\n" 1>&2
如果只想将HTTP状态码拆分到stderr,可以使用--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>
...
****注意,为了让第二个重定向能按照需要的方式进行,我们需要在subshell中运行curl命令。