在How can I use environment variables in body of a curl PUT request?中,我得到了很好的建议总是使用"
使用环境变量。
说我想做以下查询:
curl -XPUT http://"${HOST}"/create/"${USER}" -d'{"user":"'"${USER}"'"}'
我在${USER}
之间附上了"
,以确保用户名中的空格成为可能。我为${HOST}
做了同样的事情,虽然这是严格要求的,因为据我所知主机名不能包含空格。
我想知道以下请求是否等于上一个请求:
curl -XPUT "http://${HOST}/create/${USER}" -d'{"user":"'"${USER}"'"}'
他们是平等的吗?哪一个是首选/最标准?
答案 0 :(得分:1)
是的,他们是平等的。
我更喜欢
curl -XPUT "http://${HOST}/create/${USER}" -d"{\"user\":\"${USER}\"}"
首先是因为:
答案 1 :(得分:0)
正如您所见,当您拥有任意数据时,在Bash中处理引用约定很困难。但是,在这种情况下引用第三种方式比使生活更容易:"here documents"。
在shell命令中使用<<TOKEN
表示命令后面的行将被读取为命令的标准输入,以 TOKEN 结束。在这里的文档中,通常的引用字符失去了它们的特殊含义并按字面解释,但变量替换仍然正常发生。
要演示,请启动netcat“服务器”以使用
在一个终端中显示请求nc -kl localhost 8888
现在,在另一个终端中,运行此shell脚本:
name="Alice's Restaurant"
password="quote is ' and doublequote is \\\"."
curl -XPUT http://localhost:8888/create/user --data-binary @- <<EOF
{
"name": "$name",
"password": "$password",
"created": "$(date --iso-8601)"
}
EOF
当--data
参数被赋予@
时,请求curl
从@
之后立即指定的文件名中读取数据,并使用-
作为--data-binary
文件名从stdin读取。
请注意,我在这里使用--data-urlencode
来使服务器的输出更容易理解;在生产使用中,您希望使用Content-type
,或者,如果服务器接受其他格式的数据,请确保将application/x-www-form-urlencoded
标头设置为该格式,而不是将其保留为默认值{{1 }}
运行上述内容时,您将在netcat终端中看到以下内容:
PUT /create/user HTTP/1.1 Host: localhost:8888 User-Agent: curl/7.52.1 Accept: */* Content-Length: 112 Content-Type: application/x-www-form-urlencoded { "name": "Alice's Restaurant", "password": "quote is ' and doublequote is \".", "created": "2018-02-20" }
正如您所看到的,正常的引用字符不会被特别处理,您不需要对在here文档中展开的单个shell变量进行任何特殊引用,甚至可以使用$()
来运行shell命令,输出将在文档中替换。
(顺便说一句,我在密码变量中将双引号指定为\\\"
,在双引号字符串的shell插值后将其设置为\"
,因为这是必要的有效的JSON。哦,你永远无法摆脱引用问题。)