Estou tentando executar o comando jq via ssh para este 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
}
}
}
Isto é o que estou tentando executar:
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"
E esta é uma saída:
{
"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
}
}
}
Como você pode ver, o jq não funciona corretamente devido a algum problema de sintaxe com o ssh ou algo assim.
Testei este comando localmente, sem ssh, e funciona corretamente.
Acho que o problema está no printf '%s\0', mas não consegui descobrir exatamente o que estou fazendo de errado.
Responder1
A maneira mais fácil de garantir que todas as citações sejam feitas corretamente é fazer com que o shell faça isso por você, usando declare -f
para gerar uma representação textual de uma função já definida localmente e declare -p
para gerar representações textuais de quaisquer variáveis locais que a função precisa acesso a.
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"