我有一个工作的API(Linode)来更新域.因此,下面是一个正常的API调用,它可以很好地更新数据:

  #!/bin/bash

  # hardcoded data for testing
  LINODE_API_KEY=1234
  domain_id=1931316
  domain_name="abx.com"
  domain_type="master"
  domain_email="hello@abx.com"
  domain_ttl=30

  
  # Update the domain
  curl -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${LINODE_API_KEY}" \
  -X PUT -d "{

  \"domain\": \"${domain_name}\", \"type\": \"${domain_type}\", \"soa_email\": \"${domain_email}\", \"ttl_sec\": ${domain_ttl}
  
  }" "https://api.linode.com/v4/domains/${domain_id}"

当我执行上面的更新API时,它工作得很好,我得到的json响应如下:

{"id": 1931316, "type": "master", "domain": "abx.com", "tags": [], "group": "", "status": "active", "errors": "", "description": "", "soa_email": "hello@abx.com", "retry_sec": 0, "master_ips": [], "axfr_ips": [], "expire_sec": 0, "refresh_sec": 0, "ttl_sec": 30, "created": "2022-12-13T09:01:01", "updated": "2022-12-14T03:26:27"}

但问题是我想在数据中使用变量.因此,我将上面的工作代码更改为(带有我想要传递的额外数据):

  #!/bin/bash
  # hardcoded data for testing
  LINODE_API_KEY=1234
  domain_id=1931316
  domain_name="abx.com"
  domain_type="master"
  domain_email="hello@abx.com"
  domain_ttl=30
  
  # This value must be provided first
  if [ -z "${domain_name}" ]; then
     echo "You must provide domain name"
     exit 1
  else
     change_domain_name="\\\"domain\\\": \\\"${domain_name}\\\""
  fi      

  if [ -n "${domain_type} ]; then
     change_domain_type=", \\\"type\\\": \\\"${domain_type}\\\""
  else
     change_domain_type=""
  fi

  if [ -n "${soa_email} ]; then
     change_domain_email=", \\\"soa_email\\\": \\\"${domain_email}\\\""
  else
     change_domain_email=""
  fi

  if [ -n "${domain_ttl} ]; then
     change_domain_ttl=", \\\"ttl_sec\\\": ${domain_ttl}"
  else
     change_domain_ttl=""
  fi
  update_string="${change_domain_name}${change_domain_type}${change_domain_email}${change_domain_ttl}"

  # Update the domain
  curl -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${LINODE_API_KEY}" \
  -X PUT -d "{

  "${update_string}" # THE PROBLEM IS HERE WHEN USING THIS VARIABLE
  
  }" "https://api.linode.com/v4/domains/${domain_id}"

API会抱怨无效的JSON

{"errors": [{"reason": "Invalid JSON"}]}
  

但是当我使用echo ${update_string}变量时,我会得到与我使用的相同的数据语法,那么为什么它会抱怨这是无效的呢?

我甚至可以将上面的 echo 结果复制粘贴到-d数据中,它工作得很好.

我将我的问题回滚到原来的问题,以解释为什么我使用上面的方法,而不是像@Arnaud VALMARY建议的那样创建jq --arg.

例如,在这里,我只想传递值DOMAIN_NAME和DOMAIN_ttl.因此,更新字符串的值如下所示:

Update_string="${change_domain_name}${change_domain_ttl}"

其他人都是空的.所以,我不确定如何使用jq --arg实现这一点

简而言之,如果DOMAIN_TYPE=""或DOMAIN_TYPE为空,我不希望这个变量出现在--arg选项中,因此用户可以 Select 不更新此值.

推荐答案

最好使用像jq这样的专用工具来构建JSON数据.钻柱施工是危险的.

#! /usr/bin/env bash

# hardcoded data for testing
declare LINODE_API_KEY=1234
declare domain_id=1931316
declare domain_name="abx.com"
declare domain_type="master"
declare domain_email="hello@abx.com"
declare domain_ttl=30

declare json_query_data='{}'
# This value must be provided first
if [ -z "${domain_name}" ]; then
    echo "You must provide domain name"
    exit 1
else
    # shellcheck disable=SC2016
    json_query_data=$(jq --arg domain "${domain_name}" '.domain |= $domain' <<<"${json_query_data}")
fi

if [ -n "${domain_type}" ]; then
    # shellcheck disable=SC2016
    json_query_data=$(jq --arg type "${domain_type}" '.type |= $type' <<<"${json_query_data}")
fi

if [ -n "${domain_email}" ]; then
    # shellcheck disable=SC2016
    json_query_data=$(jq --arg soa_email "${domain_email}" '.soa_email |= $soa_email' <<<"${json_query_data}")
fi

if [ -n "${domain_ttl}" ]; then
    # shellcheck disable=SC2016
    json_query_data=$(jq --argjson ttl_sec "${domain_ttl}" '.ttl_sec |= $ttl_sec' <<<"${json_query_data}")
fi

# Update the domain
curl -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${LINODE_API_KEY}" \
    -X PUT \
    -d "${json_query_data}" \
    --url "https://api.linode.com/v4/domains/${domain_id}"

CURL命令为:

curl -H 'Content-Type: application/json' -H 'Authorization: Bearer 1234' -X PUT -d '{"domain":"abx.com","type":"master","soa_email":"hello@abx.com","ttl_sec":30}' --url 'https://api.linode.com/v4/domains/1931316'

Json相关问答推荐

替换字符串中特殊字符的Jolt变换

Vega图表计数聚合如果数据值为空数组则不显示任何内容,如何解决此问题?

使用Kotlin限制序列化类属性的允许整数值

在深度嵌套数组中使用布尔属性的jq-select

如何在Android中解析带有动态键和可变对象名称的改装JSON响应?

删除 JOLT 中的方括号

在 postgres 14 中将记录转换为所需的 json 格式

JOLT转换并向输出添加新数组

如何在 JSonPath 中按值查找列表中的所有元素

jq json - 按键名 Select

将 JSON 解组为具有唯一元素的 map 切片

PowerShell:如何将哈希表输出为 json 并使用 foreach 循环将其存储在变量中?

流导入错误:重新上传时不存在布局释放 UUID

在 Perl Mojolicious 中呈现 JSON 时防止转义字符

Angularjs访问本地json文件

谷歌浏览器不允许我放置断点

Jackson 中的 readValue 和 readTree:何时使用哪个?

json_encode() 返回 false

ASP.NET Web API JSON 输出中没有时间的日期

Java HashMap 与 JSONObject