如何在bash脚本中执行存储在heredoc中的curl命令?
Posted
技术标签:
【中文标题】如何在bash脚本中执行存储在heredoc中的curl命令?【英文标题】:How to execute curl command stored in heredoc in bash script? 【发布时间】:2021-12-14 23:24:07 【问题描述】:在编写 bash 脚本时,我想将整个 curl 命令存储在 heredoc
中以获得更好的布局。以下工作正常:
#/bin/bash
read -r -d '' command1 <<- MULTI_STRING_SCOPE
curl -v www.***.com
MULTI_STRING_SCOPE
但是当使用-d
选项添加一些json数据时,该命令的执行很奇怪。例如:
#/bin/bash
read -r -d '' command2 <<- MULTI_STRING_SCOPE
curl -v www.***.com
-d '
"hello":"world"
'
MULTI_STRING_SCOPE
response2=$($command2)
来自终端的错误日志:
curl: (3) URL using bad/illegal format or missing URL
curl: (3) unmatched close brace/bracket in URL position 1:
'
而且似乎 curl 将 '
行作为单独的 url,因此 json 数据没有作为一个单元发送。
如何解决问题?任何建议都将受到高度赞赏。
【问题讨论】:
将命令存储为字符串是个坏主意;它可能会使布局更好,但解析是一团糟。基本上,变量用于存储数据,而不是可执行代码。请参阅BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail! 在这种情况下,我强烈建议使用函数而不是变量。 (注意:有些人推荐eval
来处理这样的事情,但这只会引发新的解析混乱。这样会带来疯狂和非常奇怪的错误。)
@GordonDavisson 这真的很重要。我曾经了解过data and command
的故事,但我只是不知道自己陷入了这种境地。谢谢你的提示。
【参考方案1】:
我从 this post 那里学到了如何让 heredoc
使用 curl 命令。
正如@Gordon Davisson 在当前帖子中发表的评论,我们不应该将命令与数据混为一谈。由于json数据设置为-d
选项只有数据,其他部分是命令,所以我决定使用heredoc
只存储json数据,其他部分保留为命令本身,而不是通过@将它们存储在字符串中987654325@.
结果 bash 脚本应该是这样的:
#/bin/bash
response3=$(curl -v www.***.com \
-d @- <<- MULTI_STRING_SCOPE
"hello":"world"
MULTI_STRING_SCOPE
)
注意:heredoc
indent 仅适用于制表符,不适用于空格。请小心,尤其是当您使用像 Visual Studio Code
这样的编辑器时,它们可能已经为您设置了缩进为空白。
【讨论】:
这里的文档在这里提供了什么实际价值呢?只传入一个多行字符串不是更简单明了吗? @tripleee 对于我上面给出的情况,这里的文档不是必需的。在我的实际情况下,我需要使用“-d”选项以 json 格式发送数据,同时将变量替换为该 json 数据。因为json里面的双引号太多了,所以我选择-d '"json":"data"'
跟单引号一起工作,而单引号里面的变量替换好像不行,所以我转向here document
。这样有意义吗,或者也可以通过简单的多行字符串来实现?
您不能在单引号内进行变量替换。对于这种情况,here 文档实际上并不是一个糟糕的解决方案;其他解决方案包括“跷跷板引用”,如'"key" :"'"$value"'"'
(这就像用反斜杠转义所有文字双引号一样混乱)或使用像sed
这样的外部实用程序来替换静态字符串或文档中的占位符。
我学到了很多,谢谢@tripleee以上是关于如何在bash脚本中执行存储在heredoc中的curl命令?的主要内容,如果未能解决你的问题,请参考以下文章