通过 ssh 发送带有 argjson 的 jq

通过 ssh 发送带有 argjson 的 jq

我正在尝试通过 ssh 运行 jq 命令来获取此 JSON:

{
  "nodes": {
    "app": {
      "nodes": 1,
      "is_manager": true,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    },
    "data": {
      "nodes": 1,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    },
    "analysis": {
      "nodes": 1,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    },
    "elastic_kafka_1": {
      "nodes": 1,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    },
    "elastic_kafka_2": {
      "nodes": 1,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    },
    "elastic_kafka_3": {
      "nodes": 1,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    },
    "master": {
      "nodes": 1,
      "ip": [
        "0.0.0.0"
      ],
      "cpus": 16,
      "memory": 64
    }
  }
}

这就是我正在尝试运行的:

ssh -o StrictHostKeyChecking=no -i key.pem user@"172.13.1.23"
"jq -Rn --argjson original_doc \"\$(<nodes.json)\" '
  input | split(\"\u0000\") as \$ips
  | \$original_doc
  | .nodes.app.ip = \$ips[0]
  | .nodes.data.ip = \$ips[1]
  | .nodes.analysis.ip = \$ips[2]
  | .nodes.elastic_kafka_1.ip = \$ips[3]
  | .nodes.elastic_kafka_2.ip = \$ips[4]
  | .nodes.elastic_kafka_3.ip = \$ips[5]
  | .nodes.master.ip = \$ips[6]
' < <(printf '%s\0' \"\${GCP_INSTANCES[@]}\") > test.json && mv test.json nodes.json"

这是一个输出:

{
  "nodes": {
    "app": {
      "nodes": 1,
      "is_manager": true,
      "ip": "",
      "cpus": 16,
      "memory": 64
    },
    "data": {
      "nodes": 1,
      "ip": "",
      "cpus": 16,
      "memory": 64
    },
    "analysis": {
      "nodes": 1,
      "ip": null,
      "cpus": 16,
      "memory": 64
    },
    "elastic_kafka_1": {
      "nodes": 1,
      "ip": null,
      "cpus": 16,
      "memory": 64
    },
    "elastic_kafka_2": {
      "nodes": 1,
      "ip": null,
      "cpus": 16,
      "memory": 64
    },
    "elastic_kafka_3": {
      "nodes": 1,
      "ip": null,
      "cpus": 16,
      "memory": 64
    },
    "master": {
      "nodes": 1,
      "ip": null,
      "cpus": 16,
      "memory": 64
    }
  }
}

正如您所看到的,由于 ssh 或其他问题的语法问题,jq 无法正常工作。

我在本地测试了这个命令,没有使用ssh,并且可以正常工作。

我认为问题出在 printf '%s\0' 上,但无法弄清楚我到底做错了什么。

答案1

确保所有引用正确完成的最简单方法是让 shell 为您完成此操作,方法是使用declare -f生成已本地定义函数的文本表示,并declare -p生成函数所需的任何局部变量的文本表示进入。因此:

doRemoteWork() {
  jq -Rn --argjson original_doc "$(<nodes.json)" '
    input | split("\u0000") as $ips
    | $original_doc
    | .nodes.app.ip = $ips[0]
    | .nodes.data.ip = $ips[1]
    | .nodes.analysis.ip = $ips[2]
    | .nodes.elastic_kafka_1.ip = $ips[3]
    | .nodes.elastic_kafka_2.ip = $ips[4]
    | .nodes.elastic_kafka_3.ip = $ips[5]
    | .nodes.master.ip = $ips[6]
  ' < <(printf '%s\0' "${GCP_INSTANCES[@]}") >"nodes.json.$$" \
  && mv "nodes.json.$$" nodes.json
}

ssh -o StrictHostKeyChecking=no -i key.pem [email protected] \
  "$(declare -p GCP_INSTANCES; declare -f doRemoteWork); doRemoteWork"

答案2

一个明显的替代方法是承担繁重的工作本地

ssh remote-host 'cat our-document.json' |
jq 'expression...expression...expression' |
ssh remote-host 'cat >tmfile && mv tmpfile our-document.json'

相关内容