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"

값에서 가장 왼쪽의 영숫자 문자열을 찾아 사용하세요.

관련 정보