ssh remote command escape special characters when using variable

You should always enclose the command given to the ssh client for remote executing!

myuser@srv-local:~$ CMD="cat /etc/*release";ssh root@1.1.1.1 "$CMD"
Gentoo Base System release 2.0.3
myuser@srv-local:~$ CMD="cat /etc/*release";ssh root@1.1.1.1 $CMD
cat: /etc/lsb-release: No such file or directory
cat: /etc/os-release: No such file or directory
myuser@srv-remote:~$

You see the difference! The second line the special character “*” asteriks will be expanded by the shell locally and then the result will be send to the remote server for execution. In the second case the remote server will receive a command “cat /etc/lsb-release /etc/os-release” (because our local system has there two files) and not what you want “cat /etc/*release” on the remote.
We use variables above, because we want to point out

the problem, which often occurs when you use ssh remote command execution in a script.

More examples trying to escape the special character unsuccessfully:

myuser@srv-local:~$ CMD="cat /etc/*release";ssh root@1.1.1.1 $CMD
cat: /etc/lsb-release: No such file or directory
cat: /etc/os-release: No such file or directory
myuser@srv-local:~$ CMD="'cat /etc/*release'";ssh root@1.1.1.1 $CMD
bash: cat /etc/*release: No such file or directory
myuser@srv-local:~$ CMD='"cat /etc/*release"';ssh root@1.1.1.1 $CMD
bash: cat /etc/*release: No such file or directory
myuser@srv-local:~$ CMD='\'cat /etc/*release\'';ssh root@1.1.1.1 $CMD
> ^C
myuser@srv-local:~$ CMD="\'cat /etc/*release\'";ssh root@1.1.1.1 $CMD
bash: 'cat: command not found
myuser@srv-local:~$ CMD="cat /etc/\*release";ssh root@1.1.1.1 $CMD
cat: /etc/*release: No such file or directory

There is a way to escape it right without enclosing the $CMD with double quotes:

myuser@srv-local:~$ CMD="bash -c 'cat /etc/*release'";ssh root@1.1.1.1 $CMD
Gentoo Base System release 2.0.3

Of course, if you do not use variable (which is really odd to have it in a script ;-)) single or double quotes are perfectly OK:

myuser@srv-local:~$ ssh root@1.1.1.1 "cat /etc/*release"
Gentoo Base System release 2.0.3
myuser@srv-local:~$ ssh root@1.1.1.1 'cat /etc/*release'
Gentoo Base System release 2.0.3
myuser@srv-local:~$ ssh root@1.1.1.1 cat /etc/*release
cat: /etc/lsb-release: No such file or directory
cat: /etc/os-release: No such file or directory

If you do not want to escape anything no quotes is OK even with multiple arguments for the command, too:

myuser@srv-local:~$ ssh root@1.1.1.1 uname -a
Linux srv-remote 4.19.0-gentoo #3 SMP Tue Dec 20 14:56:56 GMT 2018 x86_64 Intel Xeon E3-12xx v2 (Ivy Bridge) GenuineIntel GNU/Linux

Leave a Reply

Your email address will not be published.