I have created a shell script to connect to a list of servers using sshpass and run a list of about 30 commands. An extract of the script is below.

The script will wget a new config file, but then I am stuck trying to replace a variable in the config file with the server hostname.

I've had no luck getting the remote server hostname, only the local hostname (in this case MacBookPro!) will output.

  sshpass -p "$PASSWORD" ssh -t -p 1234 $SERVER << !
   echo "Server: $SERVER"
   wget -N https://example.com/file.conf 2>&1 | grep -i "failed\|error\|saved"

attempt 1:

   replace "variabletoreplace" "$HOSTNAME" -- file.conf

attempt 2:

   sed -i "s/variabletoreplace/$(<file.conf)/"  /proc/sys/kernel/hostname

end of the script:

done <./server_list.txt

I've also attempted assigning variables like host=$(hostname -f) or $HOST, but nothing will display the remote host.

I understand in normal ssh commands this type of issue can be down to use of double-quotes instead of single-quotes, but I'm not sure how to amend the script I have whilst keeping it as a list of commands. Any help appreciated.

  • you'd save yourself a lot of effort here and be more secure, too, by using ssh keys to authenticate. Also, this is what ansible is for and you might find that would be a faster way to success than writing your own similar thing, though I'm not sure ansible supports multiple passwords per host. Good luck.
    – erik258
    Commented Sep 26, 2019 at 18:50

1 Answer 1


You need to escape the $ before the $HOSTNAME variable (or $(hostname) command), so that it is expanded/run on the remote machine rather than the local machine:

while read PASSWORD SERVER;do
  sshpass -p "$PASSWORD" ssh -t -p 1234 $SERVER << EOF
    wget -N https://example.com/file.conf 2>&1 | grep -i "failed\|error\|saved"
    sed -i "s/variabletoreplace/\$HOSTNAME/" file.conf

As mentioned in comments it would be much better to use ssh keys rather than sshpass and if all these commands you want to run were in a script on the remote host it would be a lot simpler. Alternatively using a tool like ansible or puppet may be more appropriate.

  • Unfortunately this isn't working for me. Even when I run the command from a direct SSH session: sed -i "s/variabletoreplace/\$HOSTNAME/" file.conf It's actually putting $HOSTNAME into file.conf The example I gave in my initial post did work with direct SSH connection: sed -i "s/variabletoreplace/$(<file.conf)/" /proc/sys/kernel/hostname ...but then it didn't work over sshpass. Unless you have any other ideas, I agree that putting the command into a script on the remote host is probably the way forward.
    – Peter
    Commented Sep 27, 2019 at 9:48
  • You wouldn't escape the $ if you're running in locally. Commented Sep 27, 2019 at 12:34
  • Sorry, my bad. I have repeated my earlier testing and your solution is working now. Thanks very much.
    – Peter
    Commented Sep 27, 2019 at 13:35
  • Glad to help, please accept the answer if it's working for you. Commented Sep 27, 2019 at 14:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .