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