Shell escape characters for sh -c
\
is used to escape a few characters (like \
itself, "
, $
, `
) and remove newline characters inside double quotes, so
sh -c "echo \a\\\\\b\;\c"
is like
sh -c 'echo \a\\\b\;\c'
For that sh, \
is used to escape every character, so it becomes the same as
echo 'a\b;c'
UNIX conformant echo
s expand \b
into a backspace character (^H
) which, when send to a terminal moves the cursor back one character to the left, so the ;
overwrites the a
, which is why you see ;c
.
echo
is a non-portable command whose behavior varies greatly from shell to shell and system to system. It is best avoided especially if given arguments that may contain backslashes or may start with a dash. Use printf instead.
sh -c 'printf "%s\n" "a\\\\b;c"'
to output a\\b;c
.
(3 backslashes would have been enough, but it's safer to remember that within double-quotes, you need two backslashes to get one).
For echo
implementations that expand escape sequences like yours, you'd have to double the number of backslashes.
sh -c 'echo "a\\\\\\\\b;c"'
If you want to avoid the double quotes, you'll only need to escape the ;
character which is the only one special to the shell (in addition to \
which you've already escaped in the double-quote version).
sh -c 'echo a\\\\\\\\b\;c'
If you want to use double quotes instead of single quotes, again you'll have to double the number of backslashes.
sh -c "echo a\\\\\\\\\\\\\\\\b\\;c"
And if you want to get rid of the quotes, you need to escape the space and ;
again for the outer shell.
sh -c echo\ a\\\\\\\\\\\\\\\\b\\\;c
Related videos on Youtube
Stuart
Updated on September 18, 2022Comments
-
Stuart almost 2 years
I need to execute a command with escaped argument(s) using sh -c. I know the string looks pretty ugly but simple ones don't cause a problem.
The output of the echo when passed to sh -c is different then when run stand alone and I am struggling to figure out how to fix it.
Background: [1] I am escaping the arguments to the echo command since this is passed in and I wanted to make sure extra command were not inserted. [2] I am using sh -c as I wanted to have the ability to use shell facilities like | or nohup etc.. [3] Probably not relevant but this is being run through an ssh connection to a remote server.
The command and output of the sh -c command is:
sh -c "echo \a\\\\\b\;\c" ;c
The command and output of the stand alone command is:
echo \a\\\\\b\;\c a\\b;c
Any help would be much appreciated!
-
Stuart over 11 yearsThanks for your answer (which I have accepted). Is there a way to escape the echo so that the output would be a\\b;c ?