2014-01-29 1 views
12

json 요청을 보내고 게시 데이터에 변수를 포함시키고 싶습니다. 약간의 연구를했고 변수 주위에 작은 따옴표를 사용했습니다.Bash 스크립트 : 말풍선에 문자열 변수 사용 JSON 게시 데이터

#!/bin/bash 
    FILENAME="/media/file.avi" 
    curl -i -X POST -H "Content-Type: application/json" —d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'$FILENAME'"}}}' http://192.167.0.13/jsonrpc 

불행하게도 나는 약간의 오차가 얻을 :

curl: (6) Couldn't resolve host '—d' 
curl: (3) [globbing] nested braces not supported at pos 54 
HTTP/1.1 200 OK 
Content-Length: 76 
Content-Type: application/json 
Date: Wed, 29 Jan 2014 19:16:56 GMT 

{"error":{"code":-32700,"message":"Parse error."},"id":null,"jsonrpc":"2.0"} 

이 Appearently 괄호하고 HTTP 응답 상태 몇 가지 문제가 있습니다, 명령이 실행되지 않을 수 있음. 내 코드가 뭐가 잘못 됐어? 감사합니다.

이 내 curl 버전 :

curl 7.30.0 (mips-unknown-linux-gnu) libcurl/7.30.0 OpenSSL/0.9.8y 
Protocols: file ftp ftps http https imap imaps pop3 pop3s rtsp smtp smtps tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL 
+0

이 가능성이 높은 후보'컬처럼 보인다 :

다음은 디지털 오션에 CoreOS 방울을 만드는 데 사용되는 JSON 데이터를 요청할 준비하는 예입니다 (6) '호스트를 확인할 수 없습니다 - 디부. '남자 컬 (man curl) '을하고'--data'를 찾는다. 행운을 빕니다. – shellter

+1

'd' 옵션 앞의 문자는 특별한 타이포그래피 대시처럼 보이십니까? – halfbit

+0

@ 할 빗 : 잘 잡으세요! (좋은 이름입니다!) – shellter

답변

5

나의 제안 :

#!/bin/bash 
FILENAME="/media/file 2.avi" 
curl -i -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'"$FILENAME"'"}}}' http://192.167.0.13/jsonrpc 

차이가 -d에 하이픈 (대신 대시) 및 $FILENAME 큰 따옴표입니다.

18

업데이트 : 사용하는 간단한

request_body=$(cat <<EOF 
{ 
    "jsonrpc": "2.0", 
    "method": "Player.Open", 
    "params": { 
    "item": { 
     "file": "$FILENAME" 
    } 
    } 
} 
EOF 
) 

오히려 내가 아래에 설명하는 것보다. 그러나 옵션 인 경우 jq을 사용하여 대신 JSON을 생성하십시오. 이렇게하면 $FILENAME 값이 올바르게 인용됩니다.

request_body=$(jq -n --arg fname "$FILENAME" ' 
{ 
    jsonrpc: "2.0", 
    method: "Player.Open", 
    params: {item: {file: $fname}} 
}' 

이 먼저 요청 본문의 내용으로 변수를 정의하는 것이 더 간단 할 것이다 :이 정의는 이해하는 설명이 필요할 수 있습니다

#!/bin/bash 
header="Content-Type: application/json" 
FILENAME="/media/file.avi" 
request_body=$(< <(cat <<EOF 
{ 
    "jsonrpc": "2.0", 
    "method": "Player.Open", 
    "params": { 
    "item": { 
     "file": "$FILENAME" 
    } 
    } 
} 
EOF 
)) 
curl -i -X POST -H "$header" -d "$request_body" http://192.167.0.13/jsonrpc 

하지만 두 개의 큰 이점을주의 :

  1. 따옴표의 수준을 제거하십시오
  2. 가독성을 위해 텍스트 서식을 쉽게 지정할 수 있습니다. 먼저

, 당신은 파일에서 읽는 간단한 명령 치환이 있습니다

$(< ...) # bash improvement over $(cat ...) 

대신에 파일 이름을하지만, 당신은 명령의 출력이 사용되는 공정 대체를 지정 마치 파일의 본문처럼.

프로세스 대체의 명령은 단순히 cat이며이 문서에서 읽습니다. 요청 본문이 들어있는 여기에있는 문서입니다.

+0

영리한 트릭을 붙였습니다. 감사. 완벽한 솔루션입니다. –

+0

'request_body = $ (cat << EOF ... EOF)만으로 무엇이 잘못 되었습니까? – smac89

+1

@ smac89 필자는 솔직히 왜'$ (...)'대신에'$ (<(...))'를 쓰는지 말할 수 없었다. 나는이 글을 쓰는 동안 내 머리 속에서 여러 가지 아이디어를 저글링하고있을 수도 있었는데, 이는 종종 단순화에 실패한 기괴하고 복잡한 하이브리드를 가져온다. – chepner

1

파일의 데이터를 JSON 속성에 삽입하는 또 다른 방법입니다. 이 솔루션은 jq이라는 정말 멋진 명령을 기반으로합니다.

# Load the cloud config to variable 
user_data=$(cat config/cloud-config) 

# Prepare the request data 
request_data='{ 
    "name": "server name", 
    "region": "fra1", 
    "size": "512mb", 
    "image": "coreos-stable", 
    "backups": false, 
    "ipv6": true, 
    "user_data": "---this content will be replaced---", 
    "ssh_keys": [1234, 2345] 
}' 

# Insert data from file into the user_data property 
request_data=$(echo $request_data | jq ". + {user_data: \"$user_data\"}")