Are Bash, Bourne, and Korn shells compiled into one binary in OSX?

Solution 1:

I think your basic assumption is wrong. Checking on 10.8.3:

pse@Fourecks:~$ ls -l $(type -p sh bash ksh)
-r-xr-xr-x  1 root  wheel  1333920 Oct 16  2012 /bin/bash*
-r-xr-xr-x  1 root  wheel  1380304 Oct 16  2012 /bin/ksh*
-r-xr-xr-x  1 root  wheel  1334000 Oct 16  2012 /bin/sh*
pse@Fourecks:~$ cmp -l $(type -p sh bash) | wc -l
cmp: EOF on /bin/bash
 1138124
pse@Fourecks:~$ cmp -l $(type -p sh ksh) | wc -l
cmp: EOF on /bin/sh
 1238180

Technically speaking there are some similarities between sh and bash (and the later also can be made to behave like sh) but ksh is definitively coming from a different source base:

  • http://opensource.apple.com/source/bash/bash-86.1/
  • http://opensource.apple.com/source/ksh/ksh-18/

Solution 2:

ksh and bash are completely different, but the bash and sh binaries are mostly identical. OS X's sh is a version of bash that:

  • Has POSIX mode enabled. bash doesn't comply to POSIX by default.
  • Has different startup behavior. For example sh -l doesn't read ~/.bash_profile/.
  • Has xpg_echo enabled by default. So echo acts like echo -e and it doesn't support any options.

The default FCEDIT is ed in sh but EDITOR or ed in bash:

$ diff -y --suppress-common-lines -W 80 <(strings /bin/bash) <(strings /bin/sh)
                                      > /bin/bash
${FCEDIT:-${EDITOR:-ed}}              | ${FCEDIT:-ed}
@(#)PROGRAM:bash  PROJECT:bash-86.1   | @(#)PROGRAM:sh  PROJECT:bash-86.1
$ grep -rF '${FCEDIT:-${EDITOR:-ed}}' ~/Code/Source/bash-86.1/
bash-86.1/bash-3.2/builtins/fc.c:#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"
bash-86.1/bash-3.2/builtins/fc.def:#  define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}"

The source can be downloaded from http://opensource.apple.com/tarballs/.

From man bash:

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

It doesn't emulate other aspects of the original Bourne shells though.

The original Bourne shells are no longer maintained, and /bin/sh is now meant to be some other shell that just complies to POSIX. OS X's sh allows using bashisms that don't necessarily work with the /bin/sh on other platforms (like dash on Ubuntu).