I am on a Mac Book Air, OSX 10.8.

I am trying to understand why these two snippets do not print the same output. sh -c 'echo -n 1' outputs -n 1 whereas bash -c 'echo -n 1' outputs 1 as expected.

Could you help me explaining why and how to make them output the same (if at all possible)?

  • Is there any reason why you want them to match, as in first place they are executed in two different shells? When writing shell scripts you can specify the shell to use, which should resolve many portability problems.
    – Gerry
    Oct 17 '12 at 8:58

Because apparently Mac OS is one of the systems which responds to the xpg_echo option when run in POSIX mode. Running bash as /bin/sh is equivalent to running with either --posix or setting POSIXLY_CORRECT.

The solution is to stop using echo except in cases where there can be no ambiguity. printf is the portable replacement. Never use option flags to echo, (and use printf if you do).

There are multiple incompatible historical implementations of echo which break its specification in a way that can't be fixed, and the option flags are therefore non-portable. I'm not aware of anything that currently implements POSIX echo correctly.

shopt -u xpg_echo should modify this behavior. Also as you've already discovered, not running in POSIX mode.

Also you might want to upgrade... bash 3 is getting a little crusty. Many bugs have been fixed since.

  • sh and bash --posix aren't equivalent. bash --posix also supports -n.
    – Lri
    Oct 17 '12 at 9:43
  • @LauriRanta AFAICT, they are equivalent. I initially thought that about -n as well, but not in combination with xpg_echo. You need both. If xpg_echo is enabled in POSIX mode then it appears Bash does in fact follow POSIX (with XSI rules) for echo. Note the xpg_echo behavior can be configured as default at compile-time.
    – ormaaj
    Oct 17 '12 at 10:44
  • xpg_echo is set by default in sh but unset in bash --posix, so I wouldn't say that they're equivalent. The startup behavior of sh is also different from bash --posix according to the bash man page.
    – Lri
    Oct 17 '12 at 10:59
  • @LauriRanta Interesting, well I don't have an OS X to test on and am running a git build of Bash. Perhaps with xpg_echo as default it inverts the behavior when running bash --posix. I'd have to look into it. Also, where do you see that in the manual? edit ok I know what you're talking about. I don't believe that applies to anything other than login behavior.
    – ormaaj
    Oct 17 '12 at 11:03

/bin/sh is actually a version of bash that starts up in POSIX mode (bash --posix) and also has some other changes. Another difference is that it interprets escape sequences by default:

$ bash -c "echo 'a\ba'"
$ sh -c "echo 'a\ba'"
$ sh -c "shopt -u xpg_echo; echo 'a\ba'"
$ bash --posix -c "echo 'a\ba'"

printf %s would work the same way in most environments.

You could also just write scripts for bash. OS X's sh doesn't prevent you from using Bashisms that might not work with the /bin/sh on other platforms, like dash on Ubuntu.

See also this question and the section about echo on this website.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .