shell 传递的JSON文本无效

qeeaahzv  于 2023-08-07  发布在  Shell
关注(0)|答案(3)|浏览(128)

我通过ssh合并json文件时遇到问题。我总是得到错误

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

字符串
即使我传递一个vlid json文本。

# check if the content of the input file is valid JSONn  
if ! echo "$content" | jq empty > /dev/null 2>&1; then                                               
    echo "ERROR: The content of the input file is not valid JSON."
    exit 1                                                                                        
fi                                                                
                                                 
# extract the text inside the curly brackets from the JSON content                  
extracted_content=$(echo "$content" | jq .)    
  
# check if the extracted content is valid JSON                       
if ! echo "$extracted_content" | jq empty > /dev/null 2>&1; then              
    echo "ERROR: The content of the input file contains no or invalid curly braces."  
    exit 1                                                  
fi                                                                

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


所以我试着改变路线

if ! jq --argjson data "$extracted_content" '. += $data' "$TO" > "$TO.tmp"; then


比如只执行$extracted_content或$(cat $extracted_content)。或者用echo显示$extracted_content的内容

extracted conent before ssh =
{"ntpServers":"10.9.221.1"}


也使用json验证器(https://jsonformatter.net/json-validator/)来检查文件是否有效。

wqsoz72f

wqsoz72f1#

你可以传递变量extracted_content(通过declare),然后转义美元($)符号(对于extracted_contentdata):

ssh -tt -o StrictHostKeyChecking=no -i sac_key root@${ip} -p22222 <<- _connect_
        $(declare -p extracted_content)
        # --- 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_

字符串

ne5o7dgx

ne5o7dgx2#

根据您发布的内容,extracted_content的内容是{"ntpServers":"10.9.221.1"}。将其插入到heredoc中会产生

jq --argjson data "{"ntpServers":"10.9.221.1"}" '. += $data'

字符串
在shell解析引号后,jq会收到下列参数:

  • 参数1:--argjson
  • 参数2:data
  • 参数3:'{ntpServers:10.9.221.1}
  • 参数4:. += XXX

其中,XXX是变量data的内容。你没有在你发布的代码中设置这个变量,所以我猜它是一个从父进程继承的环境变量。如果它真的是未设置的,参数4就变成了. +=
因此,jq的参数看起来不正确。

w3nuxt5m

w3nuxt5m3#

@Phillippe的答案很好,但并不完美,因为它需要您自己转义heredoc中的代码。更好的做法是让shell为您执行转义:编写要在函数中远程运行的代码,然后告诉shell使用declare -f序列化该函数,就像使用declare -p序列化该函数使用的数据一样。

remote_function() {

    # --- Append the extracted content to the target JSON ---
    jq --argjson data "$extracted_content" '. += $data' "$TO" > "$TO.tmp" || {
       rc=$?
       echo "ERROR: Error appending content to destination JSON." 
       exit "$rc"
    }

    # --- Rename the temporary file to the original target ---
    mv "$TO.tmp" "$TO"
}

ssh -tt -o StrictHostKeyChecking=no -i sac_key root@"$ip" -p22222 <<-_connect_
  $(declare -p extracted_content TO)  # define remote variables
  $(declare -f remote_function)       # define remote function
  remote_function                     # call remote function
_connect_

字符串

相关问题