如何在环境变量扩展中使用引号

时间:2018-02-19 15:17:07

标签: linux bash curl

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}"'"}'

他们是平等的吗?哪一个是首选/最标准?

2 个答案:

答案 0 :(得分:1)

是的,他们是平等的。

我更喜欢

curl -XPUT "http://${HOST}/create/${USER}" -d"{\"user\":\"${USER}\"}"

首先是因为:

  1. @Ryan在评论中说的更短
  2. 第二个文字在一个块中更具可读性,而不是连续两种引号样式
  3. 一些编辑将以更易读的方式突出显示它们(例如vim for example vim

答案 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。哦,你永远无法摆脱引用问题。)