Zend certified PHP/Magento developer

Append a line to the end of the file using ssh, sudo and sed

I have an obvious problem with quoting in bash such that I couldn’t really solve for a while. Here is a loop with executing a remote command in a sudo-subshell on a remote server via ssh:

for HOST in $RUNNER_LIST; do
  ssh -t $HOST "sudo bash -c "sed -i '$a 10.10.40.29 myhost' /etc/hosts""
done 2>/dev/null

Now, this simple approach, of course, doesn’t work. That $a gets expanded by the local shell, and since that’s an unset variable sed executes the expression ' 10.10.40.29 myhost'

I’ve tried out several approaches, and during writing this question, I somehow found out that this worked:

ssh -t $HOST "sudo bash -c "sed -i '"'$'"a 10.10.40.29 myhost' /etc/hosts""

and using prepended set -x, I see that on the remote shell, it’s expanded to

sudo bash -c 'sed '''$a 10.10.40.29 myhost''' /etc/hosts'

I was surprised since my intention was to escape $. Instead of it, the quotes got escaped. So I would like to have a clear explanation of how this expansion worked. And maybe there is a way to make this command more readable?