sh can either mean Bourne shell or /bin/sh, which is some other (POSIX-conformant) shell on most modern platforms. "The POSIX shell" is the abstract shell defined by POSIX, which is implemented by bash in POSIX mode, or ksh or dash by default. /bin/sh is sometimes also called the POSIX shell, because it's a shell that conforms to POSIX on most platforms. The original Bourne shells aren't POSIX shells.
bashref has a list of differences between bash and Bourne shells. man bash
has a list of changes when bash is invoked in POSIX mode.
/bin/sh is not a symlink or hard link on OS X, but it's almost the same size as /bin/bash:
$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x 1 root wheel 1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x 1 root wheel 1334000 Jul 26 01:52 /bin/sh
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.
The mimicking of Bourne shells is otherwise pretty limited. bash +B
(Bourne) would actually disable features like brace expansion.
$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}
But even if you disable POSIX mode, echo behaves like echo -e
by default:
$ sh
$ shopt -uo posix
$ echo '1\b2'
2
/bin/sh is dash on Ubuntu, so some bashisms work with /bin/sh on OS X but not Ubuntu.
If you actually want to write scripts for (something like) the original Bourne shells, you could use #!/usr/bin/env bash +B
instead.
I think it's easier to write scripts for bash than to avoid features that aren't part of the POSIX specifications or Bourne shells or test everything with other shells.
sh
andbash
): http://en.wikipedia.org/wiki/Comparison_of_command_shells