Kalit Inani
Kalit Inani

Reputation: 49

bash: single quotes disappear while appending text to a file

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).

Upvotes: 1

Views: 96

Answers (1)

tripleee
tripleee

Reputation: 189417

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

Upvotes: 3

Related Questions