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: $etagetagをリテラル文字列(引用符を含めるか除く)に渡すと有効な応答が得られることです。ちなみにファイルに入れて呼び出す${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のシェルから削除できます。

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

(ただし、CRを含めるように明示的に設定$(echo $etag)しない限り、パススルーがCRにどのように役立つかはわかりません。)IFS

より一般的には、元のコマンドの英数字のみが必要な場合は、出力をパイプして次のものをtr除くすべての項目を削除できます。

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

-c与えられたセットの補数を取得するために使用され、一致する-d文字を削除するために使用されます。)

もちろんこれにより、間のスペースも削除されます。

Bashでは同様のことができます。

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

値の左端の英数字文字列を見つけて使用します。

関連情報