I am trying to append a multiline text containing some single quotes(') to a file which is present on a different machine and can be only accessed through a different user. Here is my code snippet:
element_list=("element1" "element2")
for element in ${element_list[@]}
do
read -r -d '\n' CONTENT << EOM
field1 = on
field2 = '$element'
field3 = '$element-random-text'
EOM
CONFIG_FILE=/tmp/config.txt
sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -c 'echo \"$CONTENT\" >> $CONFIG_FILE'"
done
Though, the scripts execute successfully, the single quotes present in the field2 and field3 values disappear. The output appended to the file looks like:
field1 = on
field2 = element1
field3 = element1-random-text
field1 = on
field2 = element2
field3 = element2-random-text
I want those single quotes to dumped in the file too. Expected output:
field1 = on
field2 = 'element1'
field3 = 'element1-random-text'
field1 = on
field2 = 'element2'
field3 = 'element2-random-text'
Any help would be appreciated.
Note: There is a requirement to execute this command from a different machine and using the other_user(not the vm_user).
A much simpler solution is to perform all the expansion locally, and then just write the result at the end of the pipeline.
config_file=/tmp/config.txt
element_list=("element1" "element2")
for element in "${element_list[@]}"
do
read -r -d '\n' content <<____EOM
field1 = on
field2 = '$element'
field3 = '$element-random-text'
____EOM
echo "$content"
done |
sshpass -p vm_password ssh -t vm_user@<vm-ip> "sudo su - other_user -c \"cat >> '$config_file'\""
Capturing the here document only so you can then immediately echo
it is obviously a waste of memory; I imagine your real loop body looks more involved.
Don't use upper case for your private variables; see Correct Bash and shell script variable capitalization.
For robustness, I also added double quotes around ${element_list[@]}
; see When to wrap quotes around a shell variable