42 lines
1.3 KiB
Markdown
42 lines
1.3 KiB
Markdown
Title: 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:
|
|
|
|
:::bash
|
|
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` because
|
|
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 script:
|
|
|
|
:::bash
|
|
$ 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:
|
|
|
|
:::bash
|
|
$ 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:
|
|
|
|
:::bash
|
|
echo "Hello world"
|