Shell escape characters for sh -c

6,149

\ 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 echos 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
Share:
6,149

Related videos on Youtube

Stuart
Author by

Stuart

Updated on September 18, 2022

Comments

  • Stuart
    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
    Stuart over 11 years
    Thanks for your answer (which I have accepted). Is there a way to escape the echo so that the output would be a\\b;c ?