【问题标题】:Bash store json response in another variableBash 将 json 响应存储在另一个变量中
【发布时间】:2016-04-27 10:25:48
【问题描述】:

我正在卷曲一个端点:

#!/bin/bash
instance_info=$(curl -sk https://internal.admin.com/app/instance)

给出一个 json 响应:

{
"basePath": "/install", 
"metadata": {
    "deployed_artifact": "app01", 
    "docker": "True",  
    "http_port": "7471",
    "url": "www.google.com"
}, 
"name": "app-01", 
"server": "webserver1"
}

我试图避免多次卷曲以使用 JQ 从 json 中获取我需要的变量。

如果有人能告诉我如何将响应存储为另一个 var,然后使用它来变量化名称,我将不胜感激:server: url: http_port:

以下似乎运行了两次 curl:

#!/bin/bash
instance_info=$(curl -sk https://internal.admin.com/app/instance)

server_name=$(echo instance_info | /usr/bin/jq --raw-output '.server')
url=$(echo instance_info | /usr/bin/jq --raw-output '.url')

【问题讨论】:

  • 不,您的示例只运行一次 curl。
  • 我不明白为什么 curl 行会被执行两次。你怎么知道它被执行了两次?
  • 你可以使用/usr/bin/jq <args> <<< "$instance_info"来消除回声。

标签: json bash variables jq


【解决方案1】:

您只需拨打一次curl 就足够了。然后您将内容保存在一个变量中,因此您无需再次调用curl 即可访问它。

关于您的代码,您的方法很好,但在回显变量时缺少$

server_name=$(echo $instance_info | /usr/bin/jq --raw-output '.server')
#                  ^

查看示例。这里我对 JSON 进行硬编码:

your_json='
{
"basePath": "/install", 
"metadata": {
    "deployed_artifact": "app01", 
    "docker": "True",  
    "http_port": "7471",
    "url": "www.google.com"
}, 
"name": "app-01", 
"server": "webserver1"
}'

对于server

$ echo "$your_json" | jq --raw-output '.server'
webserver1

对于url,您需要指出它所在的块。即metadata:

$ echo "$your_json" | jq --raw-output '.metadata.url'
www.google.com

要存储到变量中,比如:

your_field=$(echo "$your_json" | jq --raw-output 'XXXX')
#                                                 ^^^^

【讨论】:

    【解决方案2】:

    这是一个脚本,它演示了如何使用 jq 的 @sh 格式化指令和 bash eval 来使用过滤器的输出设置 bash 变量。在这种情况下,我们对可能来自 curl 的 json 进行硬编码。

    #!/bin/bash
    instance_info='
    {
    "basePath": "/install", 
    "metadata": {
        "deployed_artifact": "app01", 
        "docker": "True",  
        "http_port": "7471",
        "url": "www.google.com"
    }, 
    "name": "app-01", 
    "server": "webserver1"
    }'
    
    eval "$(jq -M -r '@sh "server_name=\(.server) url=\(.metadata.url)"' <<< "$instance_info")"
    
    echo $server_name
    echo $url
    

    运行时会产生输出

    webserver1
    www.google.com
    

    JQ CookbookExtract data and set shell variables 部分有更多@sh 的示例。

    【讨论】:

      【解决方案3】:
      sed -rn 's/[ ]*"([^"]*)"[^"]*("[^"]*").*/\1=\2/gp'' file.json
      

      O/P:

      basePath="/install"
      deployed_artifact="app01"
      docker="True"
      http_port="7471"
      url="www.google.com"
      name="app-01"
      server="webserver1"
      

      eval这个输出可以得到变量

      eval $(sed -rn 's/[ ]*"([^"]*)"[^"]*("[^"]*").*/\1=\2/gp' file.json )
      echo $name $server
      

      O/p:

      app-01 webserver1
      

      【讨论】:

        【解决方案4】:

        通过jq 读取值然后就不需要存储json:

        read name server url http_port < <(
            curl -sk https://internal.admin.com/app/instance | \
            jq --raw-output '[.name, .server, .metadata.url, .metadata.http_port] | join(" ")'
        )
        
        echo -e "\$name: $name\n\$server: $server\n\$url: $url\n\$http_port $http_port"
        $name: app-01
        $server: webserver1
        $url: www.google.com
        $http_port 7471
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多