On OSX 10.8, if you compare the binaries for bash, sh, and ksh, a few different shell options, they are the same size. If you take it further and cmp the binaries, there seems to be only a single-byte difference between the binaries.

This superficially seems to indicate that all of the code to support all of the different shells is available in each binary, but which subset you have access to depends on which shell you end up executing.

  1. Can anyone confirm that the binaries are in fact compiled this way?
  2. From Apple's point of view, is their any benefit in combining all of the shells in this manner?

2 Answers 2


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
pse@Fourecks:~$ cmp -l $(type -p sh ksh) | wc -l
cmp: EOF on /bin/sh

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:

  • Oh yeah, you're definitely right; should have been looking at cmp -l rather than just cmp. Thanks.
    – nsg
    Commented Apr 20, 2013 at 17:19
  • 2
    Interestingly, /bin/sh actually is bash (although it'll run in sh-emulation mode based on the name). In some past versions of OS X it's been either a hard link to /bin/bash or an identical copy, but at least in 10.8.3 it's slightly different. /bin/ksh, on the other hand, is a truly different program that just happens to be about the same size. Commented Apr 20, 2013 at 18:43

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).


You must log in to answer this question.

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