curl使用bash脚本在字符串数组上循环HTTP POST

时间:2014-07-17 10:57:34

标签: arrays json bash curl

我想循环一个在bash脚本中定义的字符串数组(没有来自文件的输入参数的外部提要)。 cURL命令在循环外传递一个字符串变量时可以正常工作(参见下面的FIRST SCENARIO),但是当我尝试在循环上做类似的事情时,我无法获得HTTP响应(请参阅以下SECOND SCENARIO),我得到了:

./curlScript.sh: line N: "paramOne" : [" foo bar"]: command not found
./curlScript.sh: line N+1: "paramOne" : "foo bar": command not found
./curlScript.sh: line N+2: "paramOne" : [{"detailOne":100.0, "detailTwo":"foo bar"}]: command not found

我们的想法是在HTTP POST请求中传递JSON对象。

我尝试了不同的引用尝试:'',或者在变量$JSON_PARAM_V2周围的不同组合中没有引用,无法使其正常工作。

curlScript.sh是可执行的(chmod +x)。

以下脚本出了什么问题?

#!/bin/bash

IP_URL="localhost"
JSON_PARAM="foo bar"


# FIRST SCENARIO

curl -X POST -d '{ "paramOne" : "'"$JSON_PARAM"'" }' http://$IP_URL:8080/url_path --header "Content-Type:application/json" 

sleep 2;

# SECOND SCENARIO

jsonParametersArray=
(
    "\"paramOne\":[\"foo bar\"]"
    "\"paramOne\":\"foo bar\""
    "\"paramOne\":[{\"detailOne\":100.0,\"detailTwo\":\"foo bar\"}]\""

)

#for i in "${jsonParametersArray[@]}" do:
for ((i=0; i < ${#jsonParametersArray}; i++)) do

    JSON_PARAM_V2=i
    curl -X POST -d '{ "paramOne" : '"$JSON_PARAM_V2"' }' http://$IP_URL:8080/url_path --header "Content-Type:application/json" 

    sleep 2;

done

1 个答案:

答案 0 :(得分:3)

jsonParametersArray定义需要在定义变量名的同一行开始。使用单引号将使JSON更容易定义。

jsonParamOneArray=( 
  '["foo bar"]' 
  '"foo bar"' 
  '{"detailOne":100.0,"detailTwo":"foo bar"}'
)

您注释掉的for行是正确的(ish)行,但您要在jsonParametersArray中设置完整的JSON参数,然后在paramOne中复制curl。做一个或另一个。

for param in "${jsonParamOneArray[@]}"; do
   printf "\nCurling param [%s]\n" "$param"
   curl -X POST -d '{ "paramOne" : '"$param"' }' http://$IP_URL:8080/url_path --header "Content-Type:application/json"
   sleep 1
done

最后,在处理JSON和Web API时可能更容易不使用bash

例如,Ruby有早餐吃这类东西的模块。他们处理了大多数shell实现的边缘情况。 Ruby本身也支持转换对象tofrom JSON,因此您不需要自己尝试格式化它。

require 'rest_client'

url = "http://localhost:8080/url_path"

paramOne_values = [
  ["foo bar"],
  "foo bar",
  { :detailOne => 100.0, :detailTwo => "foo bar" }
]

paramOne_values.each |value| do
  json = { "paramOne" => value }.to_json
  puts "Request param [#{json}]"
  response = RestClient.post url, json, :content_type => :json, :accept => :json
  JSON.load response
end