对bash脚本函数中定义的变量使用curl POST

当我echo时,我得到这个,当我把它输入到终端时,它就会运行

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"

我认为我的引号有问题,但我用过很多次,也得到过类似的错误。在实际脚本中,所有变量都是用不同的函数定义的

373658 次浏览

您不需要将包含自定义标头的引号传递给curl。另外,data参数中间的变量也应该加引号。

首先,编写一个生成脚本post数据的函数。这让你避免了各种关于shell引用的麻烦,并且比在curl的调用行中输入post数据更容易阅读和维护脚本:

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"

也就是说,这里有一些关于shell引用规则的澄清:

-H参数中的双引号(如在-H "foo bar"中)告诉bash将内部内容保留为单个参数(即使它包含空格)。

--data参数中的单引号(如在--data 'foo bar'中)做同样的事情,除了它们逐字传递所有文本(包括双引号字符和美元符号)。

要在单引号文本中间插入变量,必须结束单引号,然后与双引号变量连接,并重新打开单引号以继续文本:'foo bar'"$variable"'more foo'

  • 来自Athos爵士的信息非常有效!!
下面是我如何在我的curl脚本中使用它为couchDB。这真的很有帮助 经常出去。谢谢!< / p >
bin/curl -X PUT "db_domain_name_:5984/_config/vhosts/$1.couchdb" -d '"/'"$1"'/"' --user "admin:*****"

Curl可以从文件中发布二进制数据,所以我一直在使用进程替换和利用文件描述符,每当我需要发布一些讨厌的Curl,仍然想要访问当前shell中的vars。喜欢的东西:

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,然后在不同的shell中发射上面的命令。你会看到如下内容:

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中调用subshell和引用变量。快乐黑客希望这有助于'"'"'""""'''""''

解决方案测试https://httpbin.org/和内联bash脚本
1.用于没有空格的变量,例如1:
替换所需时,只需在$variable之前和之后添加' 字符串< / p >

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

哇工作:)

几年之后,如果你使用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/"$//')

现有的答案指出curl可以从文件中发布数据,并使用heredocs来避免过多的引号转义,并清楚地将JSON分离到新的行。然而,不需要定义函数或从cat获取输出,因为curl可以发布来自标准输入的数据。我觉得这个表格很有可读性:

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

以下是我从下面的回答中得到的建议:

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'

把数据放入txt文件对我来说很有效

bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
curl --version
curl 7.29.0 (x86_64-redhat-linux-gnu)
cat curl_data.txt
{  "type":"index-pattern", "excludeExportDetails": true  }


curl -X POST http://localhost:30560/api/saved_objects/_export -H 'kbn-xsrf: true' -H 'Content-Type: application/json' -d "$(cat curl_data.txt)" -o out.json

可以使用单引号'赋值旋度变量,并将其他变量包装进去

  • 单引号=>' $变量
  • 双引号单引号=>"' $变量'"
  • 单引号+双引号+单引号=>'"' $变量

让我们测试每种情况,但首先要注意这个问题,如果我们使用单引号'进行变量赋值,则该变量不会被求值。

小心

请注意,赋值是由单引号CURL_DATA='content'完成的

cmd='ls'


CURL_DATA='{
"cmd": "$cmd",    <===== our variable
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}';


echo "$CURL_DATA";

会给我们

{
"cmd": "$cmd",    <===== we need ls not $cmd
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}

单引号' $变量'

  • 一个变量的值被求值
  • 既不单引号'也不应用双引号"
cmd='ls'


CURL_DATA='{
"cmd": '$cmd',    <===== our variable
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}';


echo "$CURL_DATA";

会给我们:

{
"cmd": ls,    <===== neither 'ls' nor "ls", just ls
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}


双引号单引号"' $变量'"

  • 变量被求值
  • 将被双引号"
cmd='ls'


CURL_DATA='{
"cmd": "'$cmd'",    <===== our variable
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}';


echo "$CURL_DATA";

会给我们

{
"cmd": "ls",    <===== we have double quote " variable "
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}

单引号+双引号+单引号=>'"' $变量

  • 变量被求值
  • 将被一个单引号'
cmd='ls'


CURL_DATA='{
"cmd": '"'$cmd'"',
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}';


echo "$CURL_DATA";

会给我们

{
"cmd": 'ls',    <===== we have a single quote ' variable '
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}

总结

# no quote at all
$cmd => $cmd


# a double quote (" $variable ")
"$cmd" => "$cmd"


# a single quote (' $variable ')
'$cmd' => ls


# a single quote + a double quote ("' $variable '")
"'$cmd'" => "ls"


# a single-double-single quote ('"' $variable '"')
'"'$cmd'"' => 'ls'

我们应该用哪一个?

由于JSON需要双引号"作为它的键或值,我们可以使用:

  • 双引号单引号"' $变量'"

旋度

cmd='ls'


CURL_DATA='{
"cmd": "'$cmd'",
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}';


echo "$CURL_DATA" | jq '.'


curl --data "$CURL_DATA" -X POST localhost:3232/cmd | jq '.'

< p >注意:
变量求值的'的等价物是'",这意味着我们可以使用'"$cmd"'而不是'$cmd',它会给我们ls,既不带单引号,也不带双引号,但如果我们需要申请旋度,就会更加混乱,因为我们需要一个双引号的结果"ls",并且必须用另一个双引号=>"'" < / p >

这段代码运行良好,但上面的代码可读性更强

cmd='ls'


CURL_DATA='{
"cmd": "'"$cmd"'",     <===== our variable
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}';


echo "$CURL_DATA" | jq '.'


curl --data "$CURL_DATA" -X POST localhost:3232/cmd | jq '.'

会给我们:

{
"cmd": "ls",    <===== result
"args": [ "-la" , "/tmp" ],
"options": {
"cwd": "/tmp"
},
"type": "sync"
}

最后

我们可以用其中任何一种:

    "cmd": "'$cmd'",    <===== will be: "ls"

    "cmd": "'"$cmd"'",    <===== will be: "ls"

"$CURL_DATA"作为普通变量

curl --data "$CURL_DATA" -X POST localhost:3232/cmd

可能有帮助:

$ export A=this B=that C=foo D=bar
$ jo -p a=$A b=$B nested=$(jo c=$C d=$D)
{
"a": "this",
"b": "that",
"nested": {
"c": "foo",
"d": "bar"
}
}

工作很好,刚刚创建了post_data函数,并在shell调用中调用它。