Curl bash可以在没有字符串操作的情况下获取标头和正文

时间:2018-12-05 15:08:13

标签: bash curl jq

我正在使用curl和bash从go cd获取配置。我需要标有ETag的标头,但也需要json主体。有没有一种简单的方法可以使用curl做到这一点,或者我必须在bash中操纵结果?

λ node app.js
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error: listen EACCES localhost
    at Server.setupListenHandle [as _listen2] (net.js:1269:19)
    at listenInCluster (net.js:1334:12)
    at Server.listen (net.js:1432:5)
    at Function.listen (c:\Moi\mirror\node_modules\express\lib\application.js:618:24)
    at Object.<anonymous> (c:\Moi\mirror\app.js:12:5)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
Emitted 'error' event at:
    at emitErrorNT (net.js:1313:8)
    at process._tickCallback (internal/process/next_tick.js:63:19)
    at Function.Module.runMain (internal/modules/cjs/loader.js:744:11)
    at startup (internal/bootstrap/node.js:285:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)

返回此:

$ curl 'https://ci.example.com/go/api/admin/pipelines/my_pipeline' \
    -u 'username:password' \
    -H 'Accept: application/vnd.go.cd.v6+json' \
    -i

我不能使用jq,因为它抱怨标头,但是我也想要ETag标头及其值。

2 个答案:

答案 0 :(得分:3)

curl返回一系列CR / LF终止的行,最后一行(后跟一个空行)为实际正文。您可以编写一个代码块,该代码块首先使用while循环从标准输入中解析出标头,并在标头块完成时终止,然后使用jq来读取其余的输入。例如:

# Consume standard input up to, and including, an empty line.
# Sets global variable 'etag'.
parse_headers () {
  local header etag_regex='ETag: (.*)'
  while read -d $'\r\n' header; do
    if [[ $header =~ $etag_regex ]]; then
      etag=${BASH_REMATCH[1]}
    elif [[ -z $header ]]; then
      # End of headers
      break
    fi
  done
}

# Pass input first to parse_headers, then to jq
{
  parse_headers
  jq '._links.self'  # After parse_headers is done, only the JSON should remain
} < <(curl ...)
echo "ETag is $etag"

示例输出

{
  "href": "https://ci.example.com/go/api/admin/pipelines/my_pipeline"
}
ETag is "e064ca0fe5d8a39602e19666454b8d77"

答案 1 :(得分:-1)

也许您应该将响应存储在变量中,并使用它来访问ETag:标头和json。

尝试一下:

response="$(curl -s 'https://ci.example.com/go/api/admin/pipelines/my_pipeline' \
-u 'username:password' \
-H 'Accept: application/vnd.go.cd.v6+json' \
-i)"
etag_header=$(printf '%s' "${response}" | sed -n '/^ETag.*/ { p }')
body_json="{${response#*{}"

# use etag_header
printf "%s\n" "${etag_header}"

# use body_json
printf "%s\n" "${body_json}" | jq

输出:

ETag: "e064ca0fe5d8a39602e19666454b8d77"
{
  "_links": {
    "self": {
      "href": "https://ci.example.com/go/api/admin/pipelines/my_pipeline"    
    }
  },
  "doc": {
    "href": "https://api.gocd.org/#pipeline-config"
  },
...