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:
- Improved port of native V7 shell for current POSIX system by Nikola Vladov.
- Heirloom Bourne Shell, which is ~SVR4/SVID3.
I tried some scripts on my system but I really couldnt find one would fail on two shells above. But, I wasnt really run those script since I didnt 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 manpage:
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}
Lets 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?).
Lets 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 didnt 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.