bash 스크립트 함수에 정의 된 변수와 함께 curl POST 사용


176

에코 할 때 터미널에 입력하면 실행됩니다.

curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data '{"account":{"email":"akdgdtk@test.com","screenName":"akdgdtk","type":"NIKE","passwordSettings":{"password":"Starwars1","passwordConfirm":"Starwars1"}},"firstName":"Test","lastName":"User","middleName":"ObiWan","locale":"en_US","registrationSiteId":"520","receiveEmail":"false","dateOfBirth":"1984-12-25","mobileNumber":"9175555555","gender":"male","fuelActivationDate":"2010-10-22","postalCode":"10022","country":"US","city":"Beverton","state":"OR","bio":"This is a test user","jpFirstNameKana":"unsure","jpLastNameKana":"ofthis","height":"80","weight":"175","distanceUnit":"MILES","weightUnit":"POUNDS","heightUnit":"FT/INCHES"}' https://xxx:xxxxx@xxxx-www.xxxxx.com/xxxxx/xxxx/xxxx

그러나 bash 스크립트 파일에서 실행될 때이 오류가 발생합니다

curl: (6) Could not resolve host: application; nodename nor servname provided, or not known
curl: (6) Could not resolve host: is; nodename nor servname provided, or not known
curl: (6) Could not resolve host: a; nodename nor servname provided, or not known
curl: (6) Could not resolve host: test; nodename nor servname provided, or not known
curl: (3) [globbing] unmatched close brace/bracket at pos 158

이것은 파일의 코드입니다

curl -i \
-H '"'Accept: application/json'"' \
-H '"'Content-Type:application/json'"' \
-X POST --data "'"'{"account":{"email":"'$email'","screenName":"'$screenName'","type":"'$theType'","passwordSettings":{"password":"'$password'","passwordConfirm":"'$password'"}},"firstName":"'$firstName'","lastName":"'$lastName'","middleName":"'$middleName'","locale":"'$locale'","registrationSiteId":"'$registrationSiteId'","receiveEmail":"'$receiveEmail'","dateOfBirth":"'$dob'","mobileNumber":"'$mobileNumber'","gender":"'$gender'","fuelActivationDate":"'$fuelActivationDate'","postalCode":"'$postalCode'","country":"'$country'","city":"'$city'","state":"'$state'","bio":"'$bio'","jpFirstNameKana":"'$jpFirstNameKana'","jpLastNameKana":"'$jpLastNameKana'","height":"'$height'","weight":"'$weight'","distanceUnit":"MILES","weightUnit":"POUNDS","heightUnit":"FT/INCHES"}'"'" "https://xxx:xxxxx@xxxx-www.xxxxx.com/xxxxx/xxxx/xxxx"

따옴표에 문제가 있다고 가정하지만 그 따옴표를 많이 사용하여 비슷한 오류가 발생했습니다. 모든 변수는 실제 스크립트에서 다른 기능으로 정의됩니다

답변:


274

사용자 정의 헤더를 묶는 따옴표를 넘기지 않아도됩니다. 또한 data인수 중간에 변수를 인용해야합니다.

먼저, 스크립트의 포스트 데이터를 생성하는 함수를 작성하십시오. 이렇게하면 쉘 인용과 관련된 모든 종류의 두통을 피할 수 있으며 컬의 호출 줄에 게시 데이터를 공급하는 것보다 스크립트를 쉽게 읽을 수 있습니다.

generate_post_data()
{
  cat <<EOF
{
  "account": {
    "email": "$email",
    "screenName": "$screenName",
    "type": "$theType",
    "passwordSettings": {
      "password": "$password",
      "passwordConfirm": "$password"
    }
  },
  "firstName": "$firstName",
  "lastName": "$lastName",
  "middleName": "$middleName",
  "locale": "$locale",
  "registrationSiteId": "$registrationSiteId",
  "receiveEmail": "$receiveEmail",
  "dateOfBirth": "$dob",
  "mobileNumber": "$mobileNumber",
  "gender": "$gender",
  "fuelActivationDate": "$fuelActivationDate",
  "postalCode": "$postalCode",
  "country": "$country",
  "city": "$city",
  "state": "$state",
  "bio": "$bio",
  "jpFirstNameKana": "$jpFirstNameKana",
  "jpLastNameKana": "$jpLastNameKana",
  "height": "$height",
  "weight": "$weight",
  "distanceUnit": "MILES",
  "weightUnit": "POUNDS",
  "heightUnit": "FT/INCHES"
}
EOF
}

그런 다음 curl을 호출 할 때 해당 기능을 사용하기 쉽습니다.

curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data "$(generate_post_data)" "https://xxx:xxxxx@xxxx-www.xxxxx.com/xxxxx/xxxx/xxxx"

여기에 쉘 인용 규칙에 대한 몇 가지 설명이 있습니다.

-H인수 의 큰 따옴표는 (와 같이 -H "foo bar") bash에게 내부에있는 것을 단일 인수로 유지하도록 지시합니다 (공백이 포함되어 있더라도).

--data인수 의 작은 따옴표는 (와 같이 --data 'foo bar') 모든 텍스트를 그대로 전달합니다 (큰 따옴표 및 달러 기호 포함).

작은 따옴표로 묶은 텍스트의 중간에 변수를 삽입하려면 작은 따옴표를 끝내고 큰 따옴표로 묶은 변수와 연결 한 다음 작은 따옴표를 다시 열어서 텍스트를 계속해야합니다 'foo bar'"$variable"'more foo'.


9
" '"$ <변수 이름> "'"은 따옴표를 생략하지 않아도되는 문제를 해결했습니다. 감사.
Usman

1
이 솔루션은 효과가 있지만 변수를 둘러싼 여분의 큰 따옴표를 방출 할 수 있다고 생각합니다. 따라서 --data '{ "account": { "email": "'"$ email " '"}}'대신 다음을 수행 할 수 있습니다. --data '{ "account": { "email": " '$ email' "}} '
twistedstream

3
두 번째 EOF 이후에 공백이 있으면 작동하지 않았습니다 EOF . 그것을 제거한 후 모든 것이 좋습니다.
Klaas

2
@dbreaux curl 명령을 실행하는 위치에 따라 다릅니다. 명령이 스크립트에있는 경우 해당 스크립트에서 그 위의 함수를 정의하면됩니다. 명령 행에서 curl을 직접 실행하는 경우 몇 가지 옵션이 있습니다. 그 중 하나는 새 파일에 함수를 입력 한 다음 명령 행 source my_new_file에서 현재 환경에서 함수를 정의하는 것입니다. 그런 다음 표시된대로 curl 명령을 실행할 수 있습니다.
아토스 경

2
@slashdottir 이것은 Here Documents라는 bash 기능입니다. 이 링크 에서 더 자세히 읽을 수 있습니다 . 특히 예 19-5를 확인하십시오. 이미 여기에 대한 전체 질문이 있습니다.
아토스 경

103

https://httpbin.org/ 및 인라인 bash 스크립트로 테스트 한 솔루션
1. 공백이없는 변수의 경우 : 예 1: 원하는 문자열을 바꿀 때 전후에
추가하십시오 .'$variable

for i in {1..3}; do \
  curl -X POST -H "Content-Type: application/json" -d \
    '{"number":"'$i'"}' "https://httpbin.org/post"; \
done

2. : 공백 입력하여
추가로 랩 변수 ""el a":

declare -a arr=("el a" "el b" "el c"); for i in "${arr[@]}"; do \
  curl -X POST -H "Content-Type: application/json" -d \
    '{"elem":"'"$i"'"}' "https://httpbin.org/post"; \
done

와우 작품 :)


1
$i공백이 포함 된 경우 에는 작동하지 않습니다 . :(
Vasyl Boroviak

예를 게시 할 수 있습니까?
pbaranski

1
확실한. i="a b"for-loop 대신
Vasyl Boroviak

5
승인 된 답변과 두 번째로 투표 된 답변이에서 작동하지 않는 것으로 나타났습니다 /bin/sh. 그러나이 답변은 트릭을 수행했습니다. 그리고 그것은 다른 답변보다 훨씬 간단합니다. 정말 고맙습니다! 더 멋진 줄 바꿈 형식으로 답변을 편집했습니다. 그렇지 않으면 광채를 찾기가 어렵습니다. 건배 친구
Vasyl Boroviak

1
감사합니다 @pbaranski 많은 시간을 절약했습니다
sudhir tataraju

32

컬은 파일에서 이진 데이터를 게시 할 수 있으므로 프로세스 대체를 사용하고 curl로 불쾌한 것을 게시해야하지만 여전히 현재 쉘의 var에 액세스하려고 할 때마다 파일 설명자를 활용했습니다. 다음과 같은 것 :

curl "http://localhost:8080" \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
--data @<(cat <<EOF
{
  "me": "$USER",
  "something": $(date +%s)
  }
EOF
)

이것은 --data @/dev/fd/<some number>일반 파일처럼 처리되는 것처럼 보입니다. 어쨌든 로컬에서 작동하려면 nc -l 8080먼저 위 명령을 실행 하고 다른 쉘에서 실행하십시오 . 다음과 같은 것을 보게 될 것입니다 :

POST / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.43.0
Accept: application/json
Content-Type:application/json
Content-Length: 43

{  "me": "username",  "something": 1465057519  }

보시다시피 heredoc에서 참조 쉘뿐만 아니라 서브 쉘 및 기타를 호출 할 수 있습니다. 행복한 해킹이 이것이 도움이되기를 바랍니다 '"'"'""""'''""''.


2
Zabbix의 경고에서 호출하려고 할 때 다른 대답이 효과가 없었습니다. 이것은 완벽하게 해결하고 더 깨끗합니다.
0rkan

그러나 bash 함수에 코드를 넣으면 어떻게 될까요? myFunction () {....}?
Hanynowsky

1
이 레시피는 스크립트가 그대로 복사 된 경우에만 작동합니다 (즉, EOF, 괄호 등을 다시 포맷하지 않음)
Vader B

9

몇 년 늦었지만 eval 또는 backtick 대체를 사용하는 경우 누군가에게 도움이 될 수 있습니다.

postDataJson="{\"guid\":\"$guid\",\"auth_token\":\"$token\"}"

sed를 사용하여 응답의 시작과 끝에서 따옴표 제거

$(curl --silent -H "Content-Type: application/json" https://${target_host}/runs/get-work -d ${postDataJson} | sed -e 's/^"//' -e 's/"$//')

4
  • 아토스 경의 정보는 완벽하게 작동했습니다!

couchDB의 curl 스크립트에서 사용하는 방법은 다음과 같습니다. 정말 많은 도움이되었습니다. 감사!

bin/curl -X PUT "db_domain_name_:5984/_config/vhosts/$1.couchdb" -d '"/'"$1"'/"' --user "admin:*****"

4

여기에 답변을 얻은 후 실제로 나를 위해 일한 것이 있습니다.

export BASH_VARIABLE="[1,2,3]"
curl http://localhost:8080/path -d "$(cat <<EOF
{
  "name": $BASH_VARIABLE,
  "something": [
    "value1",
    "value2",
    "value3"
  ]
}
EOF
)" -H 'Content-Type: application/json'

2

기존 답변에 따르면 curl은 파일에서 데이터를 게시 할 수 있으며 heredocs를 사용하여 과도한 견적 이스케이프를 피하고 JSON을 새 줄로 명확하게 나눕니다. curl은 표준 입력에서 데이터를 게시 할 수 있으므로 cat을 사용하여 함수를 정의하거나 출력을 캡처 할 필요가 없습니다. 이 양식은 매우 읽기 쉽습니다.

curl -X POST -H 'Content-Type:application/json' --data '$@-' ${API_URL} << EOF
{
  "account": {
    "email": "$email",
    "screenName": "$screenName",
    "type": "$theType",
    "passwordSettings": {
      "password": "$password",
      "passwordConfirm": "$password"
    }
  },
  "firstName": "$firstName",
  "lastName": "$lastName",
  "middleName": "$middleName",
  "locale": "$locale",
  "registrationSiteId": "$registrationSiteId",
  "receiveEmail": "$receiveEmail",
  "dateOfBirth": "$dob",
  "mobileNumber": "$mobileNumber",
  "gender": "$gender",
  "fuelActivationDate": "$fuelActivationDate",
  "postalCode": "$postalCode",
  "country": "$country",
  "city": "$city",
  "state": "$state",
  "bio": "$bio",
  "jpFirstNameKana": "$jpFirstNameKana",
  "jpLastNameKana": "$jpLastNameKana",
  "height": "$height",
  "weight": "$weight",
  "distanceUnit": "MILES",
  "weightUnit": "POUNDS",
  "heightUnit": "FT/INCHES"
}
EOF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.