如何使用 bash 和 curl 转义 json?

How to use bash and curl with escaped json?

如果我一个接一个地执行下面的两个命令,那么它们在脚本之外可以完美地工作,但是,如果我将它们放在 bash 脚本中。他们失败了。

DATA="{\"size\":500,\"sort\":{\"@timestamp\":\"desc\"},\"query\":{\"filtered\":{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"tx.traceId: AIP1447283489-6 AND event: published_notification AND attempt: 1\"}},\"filter\":{\"bool\":{\"must\":[{\"range\":{\"@timestamp\":{\"gte\":1420099200000,\"lte\":1451635199999}}}],\"must_not\":[]}}}},\"highlight\":{\"pre_tags\":[\"@kibana-highlighted-field@\"],\"post_tags\":[\"@\/kibana-highlighted-field@\"],\"fields\":{\"*\":{}}},\"aggs\":{\"2\":{\"date_histogram\":{\"field\":\"@timestamp\",\"interval\":\"1w\",\"pre_zone\":\"-08:00\",\"pre_zone_adjust_large_interval\":true,\"min_doc_count\":0,\"extended_bounds\":{\"min\":1420099200000,\"max\":1451635199999}}}},\"fields\":[\"*\",\"_source\"],\"script_fields\":{},\"fielddata_fields\":[\"log.timestamp\",\"@timestamp\",\"val\"]}"

curl -s -XPOST http://username:password@url/elasticsearch/index-*/_search -d $DATA | jq '.hits.hits[0].fields."log.timestamp"[0]'

通过使用 set -x 我发现执行的最终 curl 命令是:

curl -s -XPOST 'http://username:password@url/elasticsearch/index-*/_search' -d '{"size":500,"sort":{"@timestamp":"desc"},"query":{"filtered":{"query":{"query_string":{"analyze_wildcard":true,"query":"tx.traceId:' AIP1447283489-6 AND event: published_notification AND attempt: '1"}},"filter":{"bool":{"must":[{"range":{"@timestamp":{"gte":1420099200000,"lte":1451635199999}}}],"must_not":[]}}}},"highlight":{"pre_tags":["@kibana-highlighted-field@"],"post_tags":["@\/kibana-highlighted-field@"],"fields":{"*":{}}},"aggs":{"2":{"date_histogram":{"field":"@timestamp","interval":"1w","pre_zone":"-08:00","pre_zone_adjust_large_interval":true,"min_doc_count":0,"extended_bounds":{"min":1420099200000,"max":1451635199999}}}},"fields":["*","_source"],"script_fields":{},"fielddata_fields":["log.timestamp","@timestamp","val"]}'

如果您注意到有额外的单引号,例如:' 添加在 "query" 的值周围。如您所见:

"query":"tx.traceId:' AIP1447283489-6 AND event: published_notification AND attempt: '1"

这到底是怎么回事,我如何在脚本中将这两个命令与此 json 一起使用?

您没有在命令中引用 $DATA

curl -s -XPOST http://username:password@url/elasticsearch/index-*/_search -d $DATA

所以 $DATA 在执行参数扩展后会受到分词(以及更多)的影响。您的 $DATAquery 的值中包含空格,因此它被拆分并分成多个参数。你要的是

curl -s -XPOST http://username:password@url/elasticsearch/index-*/_search -d "$DATA"

此外,我个人的建议是用单引号将 JSON 字符串括起来,当您需要文字单引号时使用 '\''。在 shell 中用双引号引用 JSON 只会使结果无法阅读...

阅读此处文档比确保正确引用所有引号要容易得多。

url='http://username:password@url/elasticsearch/index-*/_search'
curl -s -X POST "$url" -d@- <<EOF | jq '.hits.hits[0].fields."log.timestamp"[0]'
{ "size":500,
  "sort": {
     ...
}
EOF