【问题标题】:How create multi-line curl string, with variables contained within single and double quotes?如何创建多行卷曲字符串,变量包含在单引号和双引号中?
【发布时间】:2020-06-24 13:12:42
【问题描述】:

我正在尝试使用 curl 命令向 ElasticSearch 数据库发送查询, 但是在使用 bash 脚本构建字符串时遇到了困难。

首先,不带任何变量,以下命令运行成功:

curl -XGET << "EOT" "stg-myserver.stg.xyz2.bdd.local:9200/stg_index-2020.03.10/_data?format=csv&fields_name=personId,totalPrice,regDatetime&_source=" -d '
{
  "query": { 
        "bool": {
            "filter": [{
              "range" : {
                          "regDatetime" : {
                              "gte" : "2020-03-11T08:00:00+09:00",
                              "lte" : "2020-03-11T08:59:59+09:00"
                          }
              }
            }]
        }
    }
}'
EOT

但是,当尝试将变量替换为 regDatetime 值时,查询会失败。

START_TIME='2020-03-11T08:00:00+09:00'
END_TIME='2020-03-11T08:59:59+09:00'

curl -XGET << "EOT" "stg-myserver.stg.xyz2.bdd.local:9200/stg_index-2020.03.10/_data?format=csv&fields_name=personId,totalPrice,regDatetime&_source=" -d '
{
  "query": { 
        "bool": {
            "filter": [{
              "range" : {
                          "regDatetime" : {
                              "gte" : "$START_TIME",
                              "lte" : "$END_TIME"
                          }
              }
            }]
        }
    }
}'
EOT

执行第二条语句后,我收到以下错误:

{"error":{"root_cause":[{"type":"parse_exception","re​​ason":"无法解析日期字段 [$START_TIME]...

如何访问 START_TIME 和 END_TIME?
使用heredoc是一个合理的解决方案吗,或者任何人都可以推荐一种不易出错的方法吗?

【问题讨论】:

  • 你为什么要在这里使用 here-document(&lt;&lt;"EOT" 位)?那一长串 JSON 在一个单引号参数中,所以 here-doc 最终是空的,我认为 curl 无论如何都不会尝试从中读取。

标签: bash elasticsearch curl heredoc


【解决方案1】:

您需要删除 EOT 关键字中的双引号。

curl -XGET 'stg-myserver.stg.xyz2.bdd.local:9200/stg_index-2020.03.10/_data?format=csv&fields_name=personId,totalPrice,regDatetime&_source=' -d << EOT
{ 
   ...
}
EOT 

man bash中所说:

如果单词是未引用,则此处文档的所有行都进行参数扩展(...)

也就是说,我建议使用可识别 JSON 的工具来伪造您的日期,例如 jq

jq -c -n --arg s "$START_TIME" --arg e "$END_TIME" '{ query: { bool: { filter: [ { range: { regDateTime : { gte: $s, lte: $e } } } ] }}}'

这只会在 JSON 数据中插入开始时间 s 和结束时间 e。优点是您可以确定数据是正确的 JSON。

这可以像这样与您的命令集成:

START_TIME='2020-03-11T08:00:00+09:00'
END_TIME='2020-03-11T08:59:59+09:00'
json_data=$(jq -c -n --arg s "$START_TIME" --arg e "$END_TIME" '{ query: { bool: { filter: [ { range: { regDateTime : { gte: $s, lte: $e } } } ] }}}')
url='stg-myserver.stg.xyz2.bdd.local:9200/stg_index-2020.03.10/_data?format=csv&fields_name=personId,totalPrice,regDatetime&_source='
curl -XGET "$url" -d "$json_data" 

【讨论】:

  • 感谢您的建议。是的,理想情况下,我可以使用 jq - 但不幸的是,我无权在需要的时间内在机器上安装它。另外,我尝试从 EOT 中删除双引号,但我仍然收到相同的“无法解析日期字段 [$START_TIME]”错误。
  • 我忘了提,但你必须删除你的数据周围的单引号,在-d之后
猜你喜欢
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多