json - 无法在 json --data 中使用变量

标签 json bash curl linode

我有一个可用的 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 会提示 Invalid JSON

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

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

我什至可以将上面的回显结果复制粘贴回 -d 数据中,并且工作正常。

我将我的问题回滚到原来的问题,以解释为什么我使用上述方法而不是按照@Arnaud Valmary 的建议创建 jq --arg

例如,在这里我只想传递值 domain_name 和 domain_ttl。所以更新字符串的值将是这样的:

update_string="${change_domain_name}${change_domain_ttl}"

其他人是空的。所以,我不确定如何使用 jq --arg

实现此目的

简而言之,如果 domain_type=""或 domain_type 为空,我不希望这个变量在 --arg 选项中,所以用户可以选择不更新这个值。

最佳答案

最好使用像jq这样的专用工具来构建JSON数据。 Bash 字符串构造是危险的。

#! /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 - 无法在 json --data 中使用变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74793913/

相关文章:

json - Scala:Option[Boolean] 有意义吗?

bash - 如何在 csv 中获取日期并将其从欧洲时间戳转换为 bash 中的美国格式?

php - 如何获取 3,200 条推文 (Twitter API 1.1)

php - 记录在 cron 作业中运行的 curl 的返回

python - 使用来自 JSON 响应的数据

ruby-on-rails - 阻止 Rails 尝试提供模板/ActionView::MissingTemplate

bash - 如何通过双击在 Linux 上运行脚本

php - 如何在 PHP 中使用 cURL 找到我将被重定向的位置?

c++ - RapidJSON : Differences between building using Document or Writer

linux - bash 中的备份脚本