What is the point of sh being linked to dash?
The short answer to “why the original sh shell isn't present in sh
” is that there's no original sh.
Well, ok, there is: it's the Thompson shell. Version 1 had some of the features we know today, in particular redirection and pipes (read Dennis Ritchie's paper on early Unix history). Later versions added features such as background execution with &
, globbing (implemented with an external program), and some forms of quoting, but it didn't have variables or nested control structures. Conditionals and loops were provided via external programs if
(which took one condition and one command as arguments) and goto
(which worked by changing the file position of its parent in the script file).
In 1979, in Unix V7, the Thompson shell was replaced as /bin/sh
by the Bourne shell. The first release already had many of the features that are present in dash today, and subsequent versions introduced many more. A few years later, the Korn shell came onto the scene, with a growing feature set; many Unix variants installed it under the name ksh
.
In 1992, POSIX codified a minimum set of sh
features that was basically Bourne plus a few things. Any system that called itself “Unix” had to implement at least these features. Commercial Unix systems usually used ksh as the POSIX sh, but a few (e.g. OSF/1) had their own.
Neither the Bourne shell nor the Korn shell were open source until fairly recently, so when the Linux world started to form in the mid-1990s, they weren't available. /bin/sh
had to be something else. Most Linux distributions went for bash, a shell from the GNU project that tended to be between Bourne and Korn in terms of scripting features, and much better than either for interactive use). The only viable alternative was pdksh (“public domain Korn shell”), a free (now discontinued, but living on as mksh, which is actively developed), but I don't remember a Linux distribution using pdksh as /bin/sh
, I don't know why, I guess because Linux distributions were always GNU/Linux distributions, basically shipping GNU versions of any tool for which a GNU version did exist.
There were also several open source implementations of sh
called “ash”, most notably the Almquist shell, but they were very incomplete, lacking some POSIX features that people wanted to use. A programmer who was a Debian maintainer, Herbert Xu, extended ash to make it POSIX compliant. Eventually his version was renamed to dash, and there was some push to make it /bin/sh
in Debian instead of bash. Ubuntu started out before Debian started to systematically treat bashisms (the use of bash-specific functionality in #!/bin/sh
scripts) as bugs. Both switched a later (Ubuntu 6.10, Debian only in 2009 (it was a goal for lenny but the switch was only made after the lenny release, i.e. in squeeze)).
A major reason for using dash as rather than bash as /bin/sh
is that it's significantly faster. This was especially important for Ubuntu, which has striven to keep boot times short since the beginning. Dash also tends to use less memory than bash, which is somewhat important for wrapper scripts that stay around just to do a bit of cleanup when the underlying program exits. Another benefit of dash is that it only relies on libc (the core system library) whereas bash also relies on terminal support libraries (it can't start without them, even to run a script); this means that dash has a better chance to keep working on a broken system.
At some point during the 21st century, the Korn shell went open source, and open source versions of the Bourne shell appeared (old versions, because development had ceased years before). But dash and bash were too firmly entrenched in the Linux world for them to gain any acceptance, especially the Bourne shell since its value today is only historical. Dash displaced bash because it had clear benefits, but none of the other contenders have any decisive advantage as /bin/sh
.
Speed and POSIX compliance ( in other words, portability) are the main factors. Remember that /bin/sh
is meant for system scripts, which may or may not have come from older versions of Ubuntu and/or other systems.
Sure, shiny features of bash
are cool to use for us users, but when it comes to running thing in environment where you have to manage several different servers/systems - having POSIX compliant shell makes whole lot of difference. Especially, if you're a new sysadmin and inherited environment with many scripts.
As for why original Bourne shell isn't present, it is simple - it is a proprietary product originally owned by AT&T Bell Labs.
Also, there's actually an explicit explanation on Ubuntu wiki about that:
Why was this change made? The major reason to switch the default shell was efficiency. bash is an excellent full-featured shell appropriate for interactive use; indeed, it is still the default login shell. However, it is rather large and slow to start up and operate by comparison with dash. A large number of shell instances are started as part of the Ubuntu boot process. Rather than change each of them individually to run explicitly under /bin/dash, a change which would require significant ongoing maintenance and which would be liable to regress if not paid close attention, the Ubuntu core development team felt that it was best simply to change the default shell. The boot speed improvements in Ubuntu 6.10 were often incorrectly attributed to Upstart, which is a fine platform for future development of the init system but in Ubuntu 6.10 was primarily running in System V compatibility mode with only small behavioural changes. These improvements were in fact largely due to the changed /bin/sh.
And here's a note about portability:
The Debian policy manual has long mandated that "shell scripts specifying '/bin/sh' as interpreter must only use POSIX features"; in fact, this requirement has been in place since well before the inception of the Ubuntu project. Furthermore, any shell scripts that expected to be portable to other Unix systems, such as the BSDs or Solaris, already honoured this requirement. Thus, we felt that the compatibility impact of this change would be minimal.
See https://wiki.ubuntu.com/DashAsBinSh
In GNU/Linux distributions, the "original /bin/sh
" is actually Bash.
GNU wanted a Bourne-like shell that was under the GPL, so that's why they chose Bash for their /bin/sh
, instead of Bourne, which was not GPL-licensed. Modern Linux distros inherited this decision to the point that it became a defacto standard for /bin/sh
to be Bash. The original Bourne shell ("sh") has been used in other non-Linux Unixes, even as recently as Solaris 10, but it's never been a mainstay in Linux distributions.
Switching /bin/sh
from bash to dash was a Debian decision (inherited by Ubuntu) motivated largely by speed - it came at a time when they put a huge effort into improving boot speed, and a large part of the boot CPU time at the time consistent of running init scripts.
Bash continues to be used as the default interactive/login shell for users, but Dash is the one at /bin/sh
and the one which is executed for system scripts such as init scripts.
Dash is very fast, but also is very closely POSIX-compatible - a standard that is aligned closely with the Bourne shell. So in a way, by switching from Bash to Dash we are moving back to a shell more closely aligned with Bourne.