따옴표 붙은 문자열의 따옴표를 이스케이프 처리하세요.

따옴표 붙은 문자열의 따옴표를 이스케이프 처리하세요.

curlx-www-form-urlencode 를 사용하여 파일 내에서 POST JSON 데이터를 실행 하려고 합니다 docker-compose. 이 예에서는 이 공개 웹사이트를 사용하고 있으며 다음과 같이 응답해야 합니다.

# sh -c 'curl http://httpbin.org/post -F "json={\"key\": \"value\"}"'
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "json": "{\"key\": \"value\"}"
  }, ...

이것은 외부의 작은 따옴표로 잘 작동하지만 내부에 변수가 있기 때문에 큰 따옴표가 필요합니다. 따라서 이 명령은 작동하지 않으며 중첩된 따옴표를 이스케이프 처리하는 올바른 구문을 알아낼 수 없습니다.

# sh -c "curl http://httpbin.org/post -F "json={\"key\": \"$VAR\"}""
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "json": "{key:"
  }, 

답변1

전송되는 매개변수에 삽입하려는 데이터 curl는 JSON 문서를 인코딩하는 JSON 인코딩 문자열입니다.

문자열은 다음과 같이 별도로 생성할 수 있습니다.

json_string=$( jq -n --arg 'my key' 'my "value"' '$ARGS.named|@json' )

JSON 인식 도구를 사용하여 jq데이터를 JSON 인코딩 문자열로 변환함으로써 문자열의 내용이 유효한 JSON 문자열이고 my key지정된 키, 및 를 포함하는 유효한 JSON 문서로 디코딩될 수 있는지 확인합니다. 값, my "value".

위의 정확한 명령은 문자열을 "{\"my key\":\"my \\\"value\\\"\"}"에 할당합니다 json_string.

curl그런 다음 아래와 같이 매개변수에서 이 문자열을 사용하여 직접 호출 할 수 있습니다 .

curl 'http://httpbin.org/post' -F "json=$json_string"

sh -c...또는 아래와 같이 문자열을 해당 스크립트에 매개변수로 전달하여 인라인 스크립트에서 호출할 수 있습니다.

sh -c 'curl "http://httpbin.org/post" -F "json=$1"' sh "$json_string"

이러한 호출 중 하나는 curl다음과 같은 응답을 가져옵니다.

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "json": "{\"my key\":\"my \\\"value\\\"\"}"
  },
  "headers": {
    "Accept": "*/*",
    "Content-Length": "160",
    "Content-Type": "multipart/form-data; boundary=------------------------f805cf070f665e7e",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.84.0",
    "X-Amzn-Trace-Id": "Root=1-83012651-2995681c270059da2906c40f"
  },
  "json": null,
  "origin": "xxx.xxx.xxx.xxx",
  "url": "http://httpbin.org/post"
}

JSON 문서를 JSON 문자열로 인코딩하는 것은 curl자체적으로 수행되는 것처럼 보이기 때문에 꼭 필요한 것은 아닙니다.

json_string=$( jq -n -c --arg 'my key' 'my "value"' '$ARGS.named' )

jo...JSON 문자열을 생성하거나, 설치 한 경우 더 짧은 문자열을 생성합니다.

json_string=$( jo 'my key'='my "value"' )

답변2

이와 같이?

$ var=hello
$ sh -c "curl http://httpbin.org/post -F 'json={\"key\": \"$var\"}'"
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "json": "{\"key\": \"hello\"}"
  }, 

메모:

$ sh -c "curl http://httpbin.org/post -F 'json={\"key\": \"$var\"}'"
        1                                2       3    3   34    3 21

(1) 바깥쪽 큰따옴표, (2) 작은따옴표,아니요내부 큰따옴표는 특별하므로 이스케이프할 필요가 없습니다. (3) 내부 큰따옴표는 외부 큰따옴표에 대해 이스케이프됩니다. (4) 실행하기 전에 외부 큰따옴표 안에 변수 확장을 수행합니다 sh -c(변수 값 안에 작은따옴표가 있으면 내부 셸에 문제가 발생하고 거기에 있는 큰따옴표가 JSON 구문을 엉망으로 만들 수 있다는 점에 유의하세요).

shBash이고 를 사용하여 실행하면 다음 -x과 같이 실행되는 것을 볼 수 있습니다.

+ curl http://httpbin.org/post -F 'json={"key": "hello"}'
                                  2      3   3  3     3 2 

이는 보이는 것과 거의 동일합니다 sh -c. 여기서 (2)는 인용된 문자열이고 (3)은 문자열에서 특수하지 않은 큰따옴표입니다.

(Dash의 출력이 명시적이지 않기 때문에 "Bash에서"라고 말합니다 set -x. Bash에서는 일반적으로 -x인용된 출력을 다시 실행합니다. 예를 들어 명령을 내리면 echo "foo bar"로 표시됩니다 echo 'foo bar'. 그러나 이것은 실제로 특별한 경우를 변경하지는 않습니다. ).

답변3

Heredocs를 사용하면 이 인용문을 더 쉽게 관리할 수 있습니다.

sh <<END_SCRIPT
curl http://httpbin.org/post -F 'json={"key": "$VAR"}'
END_SCRIPT

Heredoc 자체는 참조되지 않으므로 변수가 대체됩니다.

만약 VAR="foo bar", 우리는 얻는다

...
  "form": {
    "json": "{\"key\": \"foo bar\"}"
  },
...

걱정해야 할 유일한 것은 변수 값에 따옴표가 포함되어 있는지 여부입니다.

VAR='She said "Hello"'잘못된 JSON이 표시됩니다 .

...
  "form": {
    "json": "{\"key\": \"She said \"Hello\"\"}"
  },
...

쉘 매개변수 확장을 사용하여 내부 따옴표를 이스케이프 처리할 수 있습니다.

sh <<END_SCRIPT
curl http://httpbin.org/post -F 'json={"key": "${VAR//\"/\\\"}"}'
END_SCRIPT

~하도록 하다

...
  "form": {
    "json": "{\"key\": \"She said \\\"Hello\\\"\"}"
  },
...

관련 정보