【问题标题】:Having problems using curl post a json object from a variable in bash使用 curl 从 bash 中的变量发布 json 对象时遇到问题
【发布时间】:2021-06-29 11:49:02
【问题描述】:

所以我正在编写一个脚本,需要创建一个 json 对象,然后用 curl 发布它。

这是有效的:

curl --header "Content-Type: application/json" --request POST --data '{ "_type": "_test", "_device": "123.123.123.123", "_system": "web-服务”,“结果”:“成功”,“_time”:“123”,“错误”:“”}' $data_pipeline

$data_pipeline 包含发布请求的 URL

如果 $json_string 包含包含单引号的字符串: '{“_type”:“_test”,“_device”:“123.123.123.123”,“_system”:“web-services”,“结果”:“成功”,“_time”:“123”,“错误”: "" }'

这应该有效,但它没有:

curl --header "Content-Type: application/json" --request POST --data $json_string $data_pipeline

首先,我创建了不带单引号的 $json_object,并尝试将它们添加到 CURL 的命令行中。如果我不转义单引号,则 $json_string 作为文字发送,而不是扩展变量。我转义了单引号,但没有帮助,我什至尝试了双重转义以防万一,但它仍然无法正常工作。仅当我将整个 json 字符串手动放入时才有效,但如果我将其放入变量中则无效。我怎样才能解决这个问题? json 是由脚本使用 jq 动态创建的,并且 json 是有效的,因为我可以手动成功运行帖子,我只需要它与变量一起工作。没有单引号就不行,但是当我使用变量来保存json时,单引号不起作用,不管我把单引号放在变量中,还是尝试在外面做变量...我该如何解决这个问题?

json 对象是用这段代码构建的:

json_string=\'$( jq -n \
              --arg _type "$_type" \
              --arg _device "$_device" \
              --arg _system "$_system" \
              --arg result "$result" \
              --arg _time "$_time" \
              --arg error "$error" \
              '{_type: $_type, _device: $_device, _system: $_system, result: $result, _time: $_time, error: $error}' )\'

最初我创建的 json_string 没有 ' 但我添加了它以尝试将单引号包裹在 json 周围。

谢谢!

【问题讨论】:

  • 你为什么用文字单引号包裹 json?那是无效的json。您还应该引用"$json_string"
  • 因为 curl 是必需的。没有单引号的json不通过,那么curl就看不懂命令行了。当我包含单曲时,json 有效。使用 curl 发布 json 的示例还显示了使用中的单引号。我只是想在一个字符串中捕获 json,以便我的脚本可以干净地使用它。单引号中的原始 json 在我的脚本中工作正常,但是我不能使用 jq 工具来预处理 json。我尝试将 jq 命令放在 curl 命令行上,但这也不起作用。
  • @HomerTX 你试过乔丹的建议了吗?它应该可以工作(通常,您应该几乎总是在 shell 变量引用周围加上双引号)。它会起作用,因为 shell 变量中的引号(以及转义和类似的东西)与实际上是命令行一部分的引号不同。

标签: json bash curl


【解决方案1】:
#!/bin/bash

_type="hello"

# let's have some fun
_device="single'quote"
_system='double"quote'
error='multi
line'

encode()
{
    printf "%s" "$1" | sed 's/"/%22/' | tr '\n' ' '
}

# you don't need encode() if your strings are not json-offensive
json_string="{
    _type: \"$_type\"
    _device: \"$_device\"
    _system: \"$(encode "$_system")\"
    error: \"$(encode "$error")\"
}"
set -x
curl \
    -X POST \
    -d "$json_string" \
    -H 'content-type: application/json' \
    http://httpbin.org/anything

输出:

+ curl -X POST -d '{
    _type: "hello"
    _device: "single'\''quote"
    _system: "double%22quote"
    error: "multi line"
}' -H 'content-type: application/json' http://httpbin.org/anything
{
  "args": {}, 
  "data": "{\n\t_type: \"hello\"\n\t_device: \"single'quote\"\n\t_system: \"double%22quote\"\n\terror: \"multi line\"\n}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "92", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.58.0", 
  }, 
  "json": null, 
  "method": "POST", 
  "url": "http://httpbin.org/anything"
}

【讨论】:

    猜你喜欢
    • 2020-11-18
    • 2016-08-10
    • 2014-08-31
    • 2013-02-16
    • 2015-08-17
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多