将 ETag 作为 Bash 变量传递给 cURL

将 ETag 作为 Bash 变量传递给 cURL

我正在努力将我的 etag 传递给 cURL 并获得成功的响应。我得到的 etag 是:

etag=$(
  curl \
  -SIXGET \
  -u $token \
  -H "Accept: application/json" \
  "$api_url/domain-types/activation_run/collections/pending_changes" | awk '/^ETag:/ { print $2 }'

我已经验证这会返回正确的 etag。但是以下 cURL 请求失败:

curl -v -L \
  -u $token \
  -H "Accept: application/json" \
  -H "If-Match: $etag" \
  -H "Content-Type: application/json" \
  -d "{
        \"sites\": [
        \"$site\"
        ]
  }" \
  "$api_url/domain-types/activation_run/actions/activate-changes/invoke"

这里的问题是-H "If-Match: $etag,如果我将 etag 作为文字字符串(带引号或不带引号)传递,我会得到有效的响应。作为参考,,,${etag}\"$etag\"其放入文件中并调用它@etag.txt等等也不起作用。

这是错误响应:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address> ... </address>
</body></html>

上面的代码片段都位于 script.sh 文件中,调用该文件sudo ./script.sh

我正在使用 CheckMK 的 REST API。

编辑:确实:printf "etag <%q>\n" "$etag"我明白了etag <$'"e3asdajldlskj..."\r'>。添加到 etag 声明| tr -d '\r'和 cURL 请求中使用$etag可以解决问题。

答案1

在这种情况下,检查您获得的值中是否存在不可见的内容会有所帮助。比如额外的空格,或者尾随换行符等等。

这里,etag是通过命令替换设置的,它删除了尾随的换行符,所以不应该是那样,但在其他一些情况下你可能会得到一个。

要检查,请使用例如printf "etag <%q>\n" "$etag"。说明%q符至少应该在 Bash 中工作以打印引用/转义的值,以便任何空白都可见。

然后,根据您所看到的内容删除多余的内容。

您显示了尾随回车符\r,并且可以使用以下命令在 Bash 的 shell 中将其删除:

etag=${etag%$'\r'}

(不过,我看不出传递$(echo $etag)对 CR 有何帮助,除非您已IFS明确设置为包含 CR。)

更一般地说,如果您知道您只需要原始命令中的字母数字,您可以通过管道输出tr以删除除以下内容之外的任何内容:

etag=$(curl ... | tr -dc 'a-zA-Z0-9')

-c用于获取给定集合的补集,-d用于删除匹配的字符。)

当然,这也会删除中间的任何空白等。

在 Bash 中,你也可以做类似的事情

[[ $etag =~ [a-zA-Z0-9]+ ]] && etag="$BASH_REMATCH"

从值中找到最左边的字母数字字符串,并使用它。

相关内容