Using echo Portably

Problem

You are writing a script that will run on multiple versions of Unix and Linux and you need echo to behave consistently even if it is not running on bash.

Solution

Use printf "%b" whatever, or test for the system and set xpg_echo using shopt -s xpg_echo as needed.

If you omit the "%b" format string (for example, printf whatever), then printf will try to interpret any % characters in whatever, which is probably not what you want. The "%b" format is an addition to the standard printf format that will prevent that misinterpretation and also expand backslash escape sequences in whatever.

Setting xpg_echo is less consistent since it only works on bash. It can be effective if you are sure that you’ll only every run under bash, and not under sh or another similar shell that doesn’t use xpg_echo.

Using printf requires changes to how you write echo statements, but it’s defined by POSIX and should be consistent across any POSIX shell anywhere. Specifically, you have to write printf "%b" instead of just echo.

Warning

If you automatically type $b instead of %b you will be unhappy because that will print a blank line, since you have specified a null format. That is unless $b is actually defined, in which case the results depend on the value of $b. Either way, this can be a very difficult bug to find since $b and %b look very similar:

$ printf "%b" "Works"
Works

$ printf "$b" "Broken"

$

Discussion

In some shells, built-in echo behaves differently than the external echo used on other systems. This is not always obvious when running on Linux since /bin/sh is actually bash (usually;it could also be dash on Ubuntu 6.10+), and there are similar circumstances on some BSDs. The difference is in how echo does or does not expand back-slash-escape sequences. Shell built-in versions tend not to expand, while external versions (e.g., /bin/echo and /usr/bin/echo) tend to expand;but again, that can change from system to system.

Typical Linux (/bin/bash):

$ type -a echo
echo is a shell builtin
echo is /bin/echo

$ builtin echo "one	two
three"
one	two
three


$ /bin/echo "one	two
three"
one	two
three


$ echo -e "one	two
three"
one → two
three

$ /bin/echo -e "one	two
three"
one → two
three

$ shopt -s xpg_echo

$ builtin echo "one	two
three"
one → two
three

$ shopt -u xpg_echo

$ builtin echo "one	two
three"
one	two
three

Typical BSD (/bin/csh, then /bin/sh):

$ which echo
echo: shell built-in command.

$ echo "one	two
three"
one	two
three


$ /bin/echo "one	two
three"
one	two
three


$ echo -e "one	two
three"
-e one	two
three


$ /bin/echo -e "one	two
three"
-e one	two
three


$ printf "%b" "one	two
three"
one → two
three$ /bin/sh

$ echo "one	two
three"
one	two
three


$ echo -e "one	two
three"
one → two
three

$ printf "%b" "one	two
three"
one → two
three

Solaris 10 (/bin/sh):

$ which echo
/usr/bin/echo

$ type echo
echo is a shell builtin

$ echo "one	two
three"
one → two
three

$ echo -e "one	two
three"
-e one → two
three

$ printf "%b" "one	two
three"
one → two
three
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.172.146