Shell Curl返回http状态代码和响应

Shell Curl返回http状态代码和响应,shell,curl,Shell,Curl,我使用curl获取http头以查找http状态代码并返回响应。我使用命令获取http头 curl -I http://localhost 为了得到响应,我使用命令 curl http://localhost 只要使用-I标志,我就只得到标题,响应就不再存在了。有没有一种方法可以在一个命令中同时获得http响应和头/http状态代码?我可以通过查看curl文档获得一个解决方案,该文档指定使用-作为输出以将输出获取到stdout curl -o - http://localhost 为了只使用

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

curl -I http://localhost
为了得到响应,我使用命令

curl http://localhost

只要使用-I标志,我就只得到标题,响应就不再存在了。有没有一种方法可以在一个命令中同时获得http响应和头/http状态代码?

我可以通过查看curl文档获得一个解决方案,该文档指定使用
-
作为输出以将输出获取到stdout

curl -o - http://localhost
为了只使用http返回代码获得响应,我可以

curl -o /dev/null -s -w "%{http_code}\n" http://localhost
我用过这个:

    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

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

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

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

详细模式将告诉您一切

curl -v http://localhost
此命令

 curl http://localhost -w ", %{http_code}"
将获取逗号分隔的正文和状态;你可以把它们分开,把它们弄出来


您可以随意更改分隔符。

您需要的是
-i
选项:

curl -i http://localhost
-i、 --在输出中包含协议头(H/F)

或者,您可以使用详细选项:

curl -v http://localhost
-v、 ——长篇大论,让行动更具说服力


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

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,
  ...
}

我发现这个问题是因为我想独立访问响应和内容,以便为用户添加一些错误处理

Curl允许您自定义输出您可以将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}
是一个用curl替换的变量。您可以做更多的工作,或者向stderr发送代码,等等。请参阅curl手册和
--write out
选项

-w、 --写出

完成后,在标准输出上显示卷曲信息 转移格式是可能包含纯文本的字符串 文本与任意数量的变量混合。格式可以是 指定为文本“字符串”,或者您可以让curl读取 从带有“@filename”的文件中选择格式并告诉curl 要从stdin中读取格式,请写“@-”

输出格式中存在的变量将为 由curl认为合适的值或文本替换,如 如下所述。所有变量都指定为 %{variable_name}并且要输出一个正常的% 以%%计算。您可以使用\n 回车符为\r,制表符为\t

输出将写入标准输出,但是 可以使用%{stderr}切换到标准错误


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

curl-xget-w“{stderr}{\“status\”:\“{http\u code}\”,“body\”:\“{stdout}\””)-s-o-https://github.com” 2>&1
运行上面的代码,您应该返回以下格式的json:

{
"status" : <status code>,
"body" : <body of response>
}
{
“地位”:,
“正文”:
}

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

while : ; do curl -sL -w "%{http_code} %{url_effective}\\n" http://host -o /dev/null; done
为了同时获得标题和正文,我通常执行
curl-D-
,如下所示:

$curl-D-http://localhost:1234/foo
HTTP/1.1200ok
连接:保持活力
传输编码:分块
内容类型:application/json
日期:2020年7月29日星期三20:59:21 GMT
{“数据”:[“out.csv”]}
这将把头(
-D
)转储到标准输出(
-
)(在中查找
--dump header

IMHO在这方面也非常方便:

我经常使用它来格式化json数据(例如从一些RESTAPI)。但是,由于jq不需要HTTP头,所以技巧是使用
-D/dev/stderr
将头打印到stderr。请注意,这次我们还使用
-sS
(-silent,--show errors)来抑制进度表(因为我们写入管道)

$curl-sSD/dev/stderrhttp://localhost:1231/foo |jq。
HTTP/1.1200ok
连接:保持活力
传输编码:分块
内容类型:application/json
日期:2020年7月29日星期三格林尼治标准时间21:08:22
{
“数据”:[
“out.csv”
]
}
我想,如果您想将标题打印(用于快速检查)到控制台,但将正文重定向到文件(例如,当它是某种二进制文件以避免弄乱您的终端时),这也很方便:

$curl-sSD/dev/stderrhttp://localhost:1231 >/dev/null
HTTP/1.1200ok
连接:保持活力
传输编码:分块
内容类型:application/json
日期:2020年7月29日星期三格林威治标准时间21:20:02
注意:这与curl-I不同!由于
-I
将执行
HEAD
请求,而不是
GET
请求(在中查找
-HEAD
。是的:对于大多数HTTP服务器,这将产生相同的结果。但我知道许多业务应用程序根本不实现
HEAD
请求;-P

附加一行“HTTP\u 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
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
{
  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
#!/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-wrapper.sh www.google.com 
# ...the same output as pure curl would return...
echo $?
# 0
./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
------
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
$ 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]*//'
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