For a long time, since I started to use Linux to be precise, I always thought I had a true Bourne shell installed until I did:

$ type sh
sh is /bin/sh
$ file /bin/sh
/bin/sh: symbolic link to `bash'

(actually, I did ls -l /bin/sh in second command.)

The truth is almost all of us do not have a Bourne shell. We are using a mimic by Bash (or Dash, if you use Ubuntu or Debian):

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. — man bash

So, I asked “Where the hell Bourne shell is?” to myself. After some searches, I found The Traditional Bourne Shell Family. I downloaded two sources:

I tried some scripts on my system but I really couldn’t find one would fail on two shells above. But, I wasn’t really run those script since I didn’t want to have unexpected files deletion or something like that.

So, I tried to focus finding side-effect when running Bash as sh. I read one clearly written in bash(1):

Brace expansion introduces a slight incompatibility with historical versions of sh. sh does not treat opening or closing braces specially when they appear as part of a word, and preserves them in the output. Bash removes braces from words as a consequence of brace expansion. For example, a word entered to sh as file{1,2} appears identically in the output. The same word is output as file1 file2 after expansion by bash. If strict compatibility with sh is desired, start bash with the +B option or disable brace expansion with the +B option to the set command (see SHELL BUILTIN COMMANDS below).

I tested:

$ sh -c 'echo file{1,2}' # Running bash as sh
file1 file2
$ ./sh -c 'echo file{1,2}' # Heirloom
file{1,2}
$ sh +B -c 'echo file{1,2}' # Turning off brace expansion
file{1,2}
$ dash  -c 'echo file{1,2}' # Dash
file{1,2}
$ ./v7sh  -c 'echo file{1,2}' # V7 shell
file{1,2}

Let’s see what would happen if we intend to feed Bash sh with Bash syntax code:

$ bash -c 'for((i=0;i<3;i++)); do echo -n $i; done; echo'
012
$ sh -c 'for((i=0;i<3;i++)); do echo -n $i; done; echo'
012
$ ./sh -c 'for((i=0;i<3;i++)); do echo -n $i; done; echo'
./sh: syntax error at line 1: `(' unexpected
$ ./v7sh  -c 'for((i=0;i<3;i++)); do echo -n $i; done; echo'
./v7sh: syntax error at line 1: `(' unexpected
$ dash  -c 'for((i=0;i<3;i++)); do echo -n $i; done; echo'
dash: Syntax error: Bad for loop variable

No problem at all, it accepts and runs it happily and the result is correct (or incorrect?).

Let’s see the memory consumptions:

  PID USER     PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
19166 livibett  20   0 19492  2024  1552 S  0.0  0.1  0:00.03  |   |   `- bash
18890 livibett  20   0 19500  1800  1376 S  0.0  0.1  0:00.00  |   |   `- sh
18838 livibett  20   0  5632   612   508 S  0.0  0.0  0:00.00  |       `- ./sh
26010 livibett  20   0  3980   564   476 S  0.0  0.0  0:00.00  |   |   `- dash
  726 livibett  20   0  3776   400   312 S  0.0  0.0  0:00.00  |   |   `- ./v7sh

You really save not much when running Bash as sh.

File size:

884984 2010-10-10 07:34 /bin/bash
105592 2010-11-10 21:48 /bin/dash
137583 2010-11-10 21:03 sh # Heirloom
 37112 2010-11-10 22:19 sh # V7

V7 shell is creepily small and Bash is a giant.

Note: I didn’t touch compiling process for Heirloom, V7. The rest were compiled using -march=core2 -O2 -pipe -fomit-frame-pointer with emerge.

Would I install Dash, Heirloom shell, or V7 shell as my /bin/sh? The answer is no.