通过SSH合并JSON文件时遇jq报错:--argjson传入无效JSON
SSH远程执行jq合并JSON时的"invalid JSON text passed to --argjson"错误解决
问题重现
执行SSH远程合并JSON操作时,持续收到jq错误:
jq: invalid JSON text passed to --argjson
Use jq --help for help with command-line options,
or see the jq manpage, or online docs at https://stedolan.github.io/jq
本地已验证提取的JSON内容有效:
extracted conent before ssh = {"ntpServers":"10.9.221.1"}
核心脚本逻辑:
while read ip do echo "Doing changes to machine $ip" # --- Connect to machine --- cd /home/root/.ssh ssh -tt -o StrictHostKeyChecking=no -i sac_key root@${ip} -p22222 <<- _connect_ # --- Append the extracted content to the target JSON --- if ! jq --argjson data "$extracted_content" '. += $data' "$TO" > "$TO.tmp"; then echo "ERROR: Error appending content to destination JSON." exit 1 fi # --- Rename the temporary file to the original target --- mv "$TO.tmp" "$TO" _connect_ done < $1
问题根源
本地变量$extracted_content在SSH heredoc中被本地shell展开后,远程shell会对JSON字符串中的双引号进行二次解析,破坏了JSON的完整结构,导致jq接收到的不是合法的JSON文本。
解决方案
方案1:用--arg传递字符串再转JSON
将JSON作为普通字符串传递,在jq内部用fromjson解析,避开shell引号解析问题:
while read ip do echo "Doing changes to machine $ip" cd /home/root/.ssh ssh -tt -o StrictHostKeyChecking=no -i sac_key root@${ip} -p22222 <<- _connect_ if ! jq --arg data_str "$extracted_content" '. += ($data_str | fromjson)' "$TO" > "$TO.tmp"; then echo "ERROR: Error appending content to destination JSON." exit 1 fi mv "$TO.tmp" "$TO" _connect_ done < $1
方案2:通过标准输入传递JSON
将本地JSON内容通过管道传给远程jq,完全绕开变量传递的引号解析问题:
while read ip do echo "Doing changes to machine $ip" cd /home/root/.ssh echo "$extracted_content" | ssh -tt -o StrictHostKeyChecking=no -i sac_key root@${ip} -p22222 " if ! jq --argjson data \"\$(cat)\" '. += \$data' \"$TO\" > \"$TO.tmp\"; then echo 'ERROR: Error appending content to destination JSON.' exit 1 fi mv \"$TO.tmp\" \"$TO\" " done < $1
方案3:转义JSON特殊字符后传递
用printf '%q'转义JSON中的特殊字符,确保远程shell正确识别完整的JSON字符串:
# 本地先转义JSON内容 escaped_json=$(printf '%q' "$extracted_content") while read ip do echo "Doing changes to machine $ip" cd /home/root/.ssh ssh -tt -o StrictHostKeyChecking=no -i sac_key root@${ip} -p22222 <<- _connect_ if ! jq --argjson data "$escaped_json" '. += $data' "$TO" > "$TO.tmp"; then echo "ERROR: Error appending content to destination JSON." exit 1 fi mv "$TO.tmp" "$TO" _connect_ done < $1
总结
优先选择方案1或方案2,这两种方法能有效避免远程shell对JSON字符串的解析干扰,确保jq收到完整合法的JSON内容。
内容的提问来源于stack exchange,提问作者sargan26
相关产品推荐
相关产品推荐

