Issue
I am having a problem merging json files via ssh. I always get the error
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
Even though I pass a vlid json text.
# 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
So I tried to change the line
if ! jq --argjson data "$extracted_content" '. += $data' "$TO" > "$TO.tmp"; then
like doing only $extracted_content or like $(cat $extracted_content). Or showing me the contenct of $extracted_content with echo
extracted conent before ssh =
{"ntpServers":"10.9.221.1"}
Also using a json validator (https://jsonformatter.net/json-validator/) to check if the file is valid.
Solution
The answer by @Phillippe is good, but not perfect, because it requires you to escape the code in your heredoc yourself. Better practice is to have the shell do that escaping for you: Write the code you want to run remotely in a function, then tell the shell to serialize that function with declare -f
just the same as how you serialize the data the function uses with 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_
Answered By - Charles Duffy Answer Checked By - Pedro (WPSolving Volunteer)