Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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!

share|improve this question

1 Answer 1

up vote 2 down vote accepted

\ 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|improve this answer
    
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 ? –  Stuart Dec 6 '12 at 22:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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