我使用curl来获取http标头以查找http状态代码并返回响应。我使用命令
获取http标头curl -I http://localhost
要获得回复,我使用命令
curl http://localhost
只要使用-I标志,我只获得标题,响应不再存在。有没有办法在一个命令中同时获取http响应和headers / http状态代码?
答案 0 :(得分:53)
我能够通过查看指定使用的curl doc来获得解决方案 - 输出将输出输出到stdout。
curl -o - http://localhost
要仅使用http返回码获取响应,我就可以
curl -o /dev/null -s -w "%{http_code}\n" http://localhost
答案 1 :(得分:20)
我使用此命令打印状态代码而没有任何其他输出。此外,它只会执行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 ]'
答案 2 :(得分:16)
详细模式会告诉你一切
curl -v http://localhost
答案 3 :(得分:11)
我用过这个:
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
答案 4 :(得分:4)
-i
选项是您想要的选项:
curl -i http://localhost
-i,--include在输出(H / F)中包括协议标头
或者,您可以使用详细选项:
curl -v http://localhost
-v,--verbose使操作更健谈
答案 5 :(得分:4)
单行,只是为了获取状态代码:
curl -s -i https://www.google.com | head -1
将其更改为 head -2
也会给时间。
如果你想要一个 while-true 循环,它会是:
URL="https://www.google.com"
while true; do
echo "------"
curl -s -i $URL | head -2
sleep 2;
done
产生以下结果,直到您执行 cmd+C
(或在 Windows 中执行 ctrl+C
)。
------
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
答案 6 :(得分:3)
我实现这一目标的方法:
要同时获得(标题和正文),我通常会执行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
)转储到标准输出(-
)(在man curl中查找--dump-header
)。
在这种情况下,恕我直言也很方便:
我经常使用jq来格式化json数据(例如,从其他REST API获取)。但是,由于jq不需要HTTP标头,因此窍门是使用-D/dev/stderr
将标头打印到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
请求(在man curl中查找--head
。是的:对于大多数HTTP服务器,这将产生相同的结果但是,我知道很多业务应用程序根本没有实现HEAD
请求;-P
答案 7 :(得分:3)
$ curl -kv https://www.example.org
$ curl -kv https://www.example.org 2>&1 | grep -i 'HTTP/1.1 ' | awk '{print $3}'| sed -e 's/^[ \t]*//'
答案 8 :(得分:3)
这里有一些不错的答案,但就像我发现自己在脚本上下文中想要的 OP 一样:
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" "$?")
然后可以在变量中找到结果:
echo out $out
echo http_code $http_code
echo status $status
结果:
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
该脚本通过多路复用输出、HTTP 响应代码和 curl
退出状态(由空字符分隔)来工作,然后将这些读回当前 shell/脚本。可以使用 curl
请求进行测试,这些请求将返回 >=400 响应代码但也会产生输出。
请注意,如果没有 -f
标志,当服务器返回异常 HTTP 响应代码(即 >=400)时,curl
不会返回非零错误代码,并且带有 -f
标志,服务器输出在错误时被抑制,利用此标志进行错误检测和处理没有吸引力。
带有 IFS 处理的通用 read
的积分转到此答案:https://unix.stackexchange.com/a/430182/45479 .
答案 9 :(得分:2)
我发现了这个问题,因为我想同时提供响应和内容,以便为用户添加一些错误处理。
您可以打印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
答案 10 :(得分:2)
对于编程用途,我使用以下内容:
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,
...
}
答案 11 :(得分:2)
function cg(){
curl -I --silent www.google.com | head -n 1 | awk -F' ' '{print $2}'
}
cg
# 200
欢迎使用我的 dotfile 脚本 here
--silent
:使用管道时不显示进度条head -n 1
:只显示第一行-F' '
:使用分隔符空格按列分隔文本'{print $2}'
:显示第二列答案 12 :(得分:1)
在行末添加“ http_code:200”行,然后grep关键字“ http_code:”并提取响应代码。
result=$(curl -w "\nhttp_code:%{http_code}" http://localhost)
echo "result: ${result}" #the curl result with "http_code:" at the end
http_code=$(echo "${result}" | grep 'http_code:' | sed 's/http_code://g')
echo "HTTP_CODE: ${http_code}" #the http response code
在这种情况下,您仍然可以使用非静音模式/详细模式来获取有关请求的更多信息,例如curl响应正文。
答案 13 :(得分:1)
根据我的经验,我们通常以这种方式使用curl
curl -f http://localhost:1234/foo || exit 1
curl: (22) The requested URL returned error: 400 Bad Request
通过这种方式,我们可以在卷曲失败时传递卷曲,并且还显示状态代码。
答案 14 :(得分:0)
这是一种检索主体“与”状态代码并将其格式化为适当的json或任何适合您的格式的方法。有人可能会争辩说这是对write format选项的错误使用,但是当我在脚本中同时需要正文和状态代码来检查状态代码并中继来自服务器的响应时,这对我有用。
curl -X GET \
-w "%{stderr}{\"status\": \"%{http_code}\", \"body\":%{stdout}}" -s -o - \
"https://jsonplaceholder.typicode.com/posts?userId=1" 2>&1 | jq
运行上面的代码,您应该以以下格式返回json:
{
"status" : <status code>,
"body" : <body of response>
}
使用-w写格式选项,因为先打印stderr,所以可以使用var http_code格式化输出,并将响应的正文放置在一个值(正文)中,然后使用var stdout进行后续封装。然后将您的stderr输出重定向到stdout,您将能够将http_code和响应正文组合成一个整洁的输出
答案 15 :(得分:0)
哇,这么多答案,cURL 开发人员肯定把它留给我们作为家庭练习:) 好的,这是我的看法 - 一个使 cURL 按预期工作的脚本,即:
另存为 curl-wrapper.sh
:
#!/bin/bash
output=$(curl -w "\n%{http_code}" "$@")
res=$?
if [[ "$res" != "0" ]]; then
echo -e "$output"
exit $res
fi
if [[ $output =~ [^0-9]([0-9]+)$ ]]; then
httpCode=${BASH_REMATCH[1]}
body=${output:0:-${#httpCode}}
echo -e "$body"
if (($httpCode < 200 || $httpCode >= 300)); then
# Remove this is you want to have pure output even in
# case of failure:
echo
echo "Failure HTTP response code: ${httpCode}"
exit 1
fi
else
echo -e "$output"
echo
echo "Cannot get the HTTP return code"
exit 1
fi
那么一切照旧,但不是curl
,而是./curl-wrapper.sh
:
所以当结果落在 200-299 范围内时:
./curl-wrapper.sh www.google.com
# ...the same output as pure curl would return...
echo $?
# 0
当结果超出 200-299 范围时:
./curl-wrapper.sh www.google.com/no-such-page
# ...the same output as pure curl would return - plus the line
# below with the failed HTTP code, this line can be removed if needed:
#
# Failure HTTP response code: 404
echo $?
# 1
不要传递“-w|--write-out”参数,因为这是在脚本中添加的内容
答案 16 :(得分:0)
我使用以下方法在控制台中同时获取 return code
和 response body
。
注意 - 使用 tee
将输出附加到文件和控制台中,这解决了我的目的。
Sample CURL call for reference:
curl -s -i -k --location --request POST ''${HOST}':${PORT}/api/14/project/'${PROJECT_NAME}'/jobs/import' \
--header 'Content-Type: application/yaml' \
--header 'X-Rundeck-Auth-Token: '${JOB_IMPORT_TOKEN}'' \
--data "$(cat $yaml_file)" &>/dev/stdout | tee -a $response_file
return_code=$(cat $response_file | head -3 | tail -1 | awk {'print $2'})
if [ "$return_code" != "200" ]; then
echo -e "\Job import api call failed with rc: $return_code, please rerun or change pipeline script."
exit $return_code
else
echo "Job import api call completed successfully with rc: $return_code"
fi
希望这对一些人有所帮助。
答案 17 :(得分:-2)
while : ; do curl -sL -w "%{http_code} %{url_effective}\\n" http://host -o /dev/null; done