Bash

通過 ssh 使用 argjson 發送 jq

  • April 30, 2022

我正在嘗試通過 ssh 為這個 JSON 執行 jq 命令:

{
 "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’ 上,但無法弄清楚我做錯了什麼。

確保正確完成所有引用的最簡單方法是讓 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 user@172.13.1.23 \
 "$(declare -p GCP_INSTANCES; declare -f doRemoteWork); doRemoteWork"

引用自:https://unix.stackexchange.com/questions/547233