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";
  • 4
    Have you tried using single quotes on the command substitution? – Jesse_b Feb 12 '18 at 15:24
  • 2
    can you give a more complete example? ssh host1 'echo "$(hostname)"' is a rather complicated way to say ssh host1 hostname – thrig Feb 12 '18 at 15:24
  • I added an explanation. – Timothy Pulliam Feb 12 '18 at 15:56
  • Did you try @Jesse_b 's suggestion? – Andy Dalton Feb 12 '18 at 16:00
  • @Jesse_b's suggestion for single quotes did the trick. Thanks. – Timothy Pulliam Feb 12 '18 at 16:01

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
  • 1
    Thank you for detailing one of the finer points of BASH. – Timothy Pulliam Feb 12 '18 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.