echo and backslash-escaped caracters / new lines: how to write portable scripts ?

While writing shell scripts you are using a lot of ‘echo’ but did you think about portability of this simple statement ?

Can you say what will be diplayed, without testing, on your shell, the following tests :

echo \n \c '\n' '\c' "\n" "\c"
echo -e \n \c '\n' '\c' "\n" "\c"

?

I can’t, cause I know that the echo behavior is very implementation dependent, typically in dash, echo -e foo actually print ‘-e foo’ cause the dash’s echo don’t parses any options …

Here is the bug I found on one of my shell scripts, simplified to this 9 bytes shell scripts :

$ cat /tmp/test.sh
#!/bin/sh
echo "$*"
$ /tmp/test.sh '1\n2'
1
2

I’m running Debian Squeeze so my sh is a dash, and the ‘\n’ is interpreted by the dash’s echo … but I don’t want it !
The only portable workaround I found is :

$ cat /tmp/test.sh
#!/bin/sh
printf "%s\n" "$*"
$ /tmp/test.sh '1\n2'
1\n2

Conclusion: Keep a look at your input, if you don’t want backslash-escaped chars to be interpreted and want to be portable, use printf !
You can keep using echo when you have a full control on the input, so the sh Hello World will forever stay :

echo "Hello world"
This entry was posted in Shell Script. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>