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

curl -I http://localhost

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

curl http://localhost

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


当前回答

对于编程使用,我使用以下代码:

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

其他回答

这里有一些很好的答案,但就像我发现自己想要的OP一样,在脚本环境中,所有的:

服务器返回的任何响应体,而不管响应状态码:有些服务会发送错误细节,例如当响应是错误时,会以JSON形式发送 HTTP响应代码 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处理的通用读取的学分转到这个答案:https://unix.stackexchange.com/a/430182/45479。

一个清晰的使用管道读取

function cg(){
    curl -I --silent www.google.com | head -n 1 | awk -F' ' '{print $2}'
}
cg
# 200

欢迎在这里使用我的dotfile脚本

解释

——silent:使用管道时不显示进度条 head -n 1:只显示第一行 -F' ':使用分隔符分隔文本 '{print $2}':显示第二列

仅捕获响应: curl——location——请求GET“http://localhost:8000” 捕获响应和它的状态码: curl——location——request GET "http://localhost:8000" -w "%{http_code}" 在文件中捕获响应: curl——location——request GET "http://localhost:8000" -s -o "response.txt"

我使用以下方法在控制台中获得返回代码和响应体。

注:使用tee将输出附加到一个文件以及控制台,这解决了我的目的。

示例CURL调用供参考:

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

希望这能帮助到一些人。

详细模式会告诉你一切

curl -v http://localhost