2

I want to do something like the following in a script

$ ssh host1 "$(command)"

However, the sub processes gets executed before the SSH connection is established because if I do the following

$ ssh host1 "$(hostname)"

the hostname of the local machine is returned. I want to be able to use sub processes because it would make other things I am trying to do easier.

Edit: A more complete example as requested. I have a list of hostnames that I need to add crontab entries to. Each system belongs to a specific user and so should have the entry added in their name. The owner of the system is contained in the hostname of the system, so by parsing the hostname, I can su to the appropriate user and edit their crontab accordingly. For example something like this:

for host in $(cat /tmp/hosts); do
echo -e "----------------------------"
echo -e "# SSH to host $host"
echo -e "----------------------------"
ssh $host "su - $(hostname | cut -b-5-); crontab -e";
done

1 Answers1

4

Your command substitution is expanding locally because the double quotes allow the shell to.

The double quote will allow the shell to interpret $, `, \, and if history expansion is enabled !

Single quotes on the other hand will preserve the literal value of all special characters.

So when you single quote your command substitution you are ensuring that it is passed to the remote machine as is. You could also use the escape character for this if you had to preserve a local variable as part of your command substitution.

ssh user@host "$(command)"    #will expand locally
ssh user@host '$(command)'    #will expand on the remote machine
ssh user@host "\$(command $local_var)"    #will expand local_var locally but send the command substitution to the remote machine
jesse_b
  • 37,005