13-11-2003
This page is about all the variants of the original Bourne shell, it does't deal with bourne compatible shells (korn, almquist, bourne again, etc.)
Originally, this started with a rough english translation of <3B9529F8.2RV1IN16U@bigfoot.de> from de.comp.os.unix.shell. Credits for that posting and for countless further comments to Gunnar Ritter. Without The Unix Heritage Society (TUHS) the first half of this page wouldn't have been possible. Many thanks also to Dennis Ritchie for documentation about the Version 8 shell and to Warren Toomey (TUHS) for documentation about the SVR1 shell.
I inspected the Bourne shell on these unix systems. If you have access to a different one, i really would like to hear from you.
Keep in mind that the Bourne shell is not necessarily
/bin/sh [1].
Find more information about the origins of the Bourne shell at the bottom of this page.
Todo: Bourne shell before Version 7 (unreleased), a better look at the various SVR4.x
An often undocumented but characteristic feature common to all traditional Bourne shells (except for "Version 8") which is not existent in other shells: You can use the circumflex '^' (caret) as replacement for the pipe symbol '|'. See more common characteristics of the traditional Bourne shells distinguishing them from their successors.
The item "Version 7 " only lists some main differences to current shells.
See also the linked manual page for more information.
All subsequent items list the differences (new features as well as
bugfixes) to predecessors; i.e., go backwards to nail down the V7 shell.
/etc/profile (i.e., no global profile)
unset" facility (i.e., no way to remove
variables from the environment)
[" available,
neither as built-in, nor as external command on Version 7 (but only
the external "test").
#', is not a comment character yet.
(Instead, comments are only available via the null-command,
':' (colon), but naturally not without possible side
effects, e.g., " : `echo output 1>&2`")
chdir" as synonym for "cd", apparently for
backwards compatibility to the Thompson shell (undocumented)
/bin/csh if
the first character of an executable script is '#'
(the #! kernel
mechanism came later)
sh, SINIX 5.20,
SunOS 1.x and 2.x):
comment character '#'.
sh: "ulimit [-f]" built-in,
/etc/profilesh,
SINIX 5.20 [4],
2.10BSDff. "backport",
SunOS 1.x and 2.x )
/etc/profile
#'
${parameter:=word}"
test", aka "[", added
(the latter actually was always existent in code, but commented out)
[...]" , e.g., "[!0-9]"
(not documented yet)
set" recognizes "--" as option
delimiter, for arguments with a leading "-"
or "+"
set" knows "+" to unset a
respective switch
fork checking improved, new error messages
"cannot fork: too many processes" and "...: no swap space".
read" strips the leading IFS characters (undocumented)
read" recognizes multiple IFS characters as one
field delimiter when reading several variables (undocumented)
if false ;then :;fi;echo $?" formerly
wrongly yielded the exit status of false
(essential fix for the "-e" flag)
"$@" (or ${1+"$@"}),
empty arguments are not discarded anymore
<<-" strips leading tabs
-r") added.
The environment variable "SHELL" is inspected at start-up.
Formerly, the "-r" flag was accepted and even
listed under SYNOPSIS but neither implemented nor mentioned otherwise.
exit" allows leaving an interactive shell now
chdir" deactivated (undocumented)
read" doesn't strip the leading IFS characters
read" doesn't recognize multiple IFS characters
as one field delimiter when reading several variables
display" built-in identical to
the "echo" utility. Note: the echo built-in
comes in SVR2.
chdir" not deactivated
ulimit"
shift" accepts a number
cd" knows CDPATH
& or ``)cat<<EOF& ..."
or "a=`cat<<EOF ...`"
(was: "/tmp/sh12345: cannot open")
-p to check for named pipe
return" built-in)
echo pwd type unset hash"
set | pg" or "read variable < file"
-afh"
continue n" works always (you couldn't
jump out of the outermost loop before)
eval 'echo foo>a' >b" (was: "illegal io")
readonly without arguments doesn't list the exported
variables anymore
MAILCHECK, MAILPATH
-h to check for symbolic links
sh5, SunOS 3.x )
HISTORY, pointing to a writable
file, providing a history mechanism via
"=(1)"
type" is replaced by "whatis"
which produces output that can be re-evaluated by the shell
-p": removing function-definitions imported
from environment, setting IFS back to default value
echo test hash pwd ulimit" and their
implications are gone
builtin", assuring that nothing else is
called instead (e.g., a function),
also needed for "whatis"
{' and '}' are special
like '(' and ')',
i.e., syntactically equivalent (e.g., leading blank
and terminating delimiter aren't necessary anymore,
redirection may also appear at the left side)
[...]" with '^',
instead of '!', e.g., "[^0-9]"
:' and its side effects or with
";;" in "case" )
^' is gone
/etc/profile
SHELL and "readonly" are also gone)
<<-" (strip leading tabs in here documents)
cd" provides an automatic spell checker
f()command>x" works (was: "syntax error").
Note that the redirection always, even with braces, ends
in the body, though. (also in POSIX.2)
MAILCHECK and MAILPATH are gone
(MAIL is kept)
LC_CTYPE/LC_COLLATE
BIN_SH (<empty>/posix/svr4).
ulimit" doesn't only know about file
size, but is implemented with the 4.2BSD/SVR4-like
getrlimit(2)
[...]"
cat <<`...`" anymore
(and the backquotes have no special meaning)
test" knows -L and -h to check
for symbolic links, and -e to check for existence
argv[0]
is rsh or -rsh.
*/" and
".*/" to directories.
umask: Improper mask" error message added
cd"
(linked in from libc) instead of only "bad directory"
TIMEOUT mechanism activated
type" returns false on "[...]: not found"
LC_CTYPE/LC_COLLATE
[...]"
-h to check for symbolic links
pwd" knows "-H"
for socalled context dependent files, cdf(4)
argv[0]
is rsh or -rsh.
cd" with more detailed error messages:
"not a directory", "does not exist", "permission denied",
"Multihop attempted", "remote link inactive".
Formerly, there was only "bad directory".
getopts"
[...]"
IFS='\' wrongly doesn't split anymore
(demonstrate with var='x\y';set $var;echo "x:$1 y:$2")
PATH
did not
mean "." before (however, it should behave like execvp(2))
r' is somewhere in
argv[0], but only for rsh and -rsh.
var=x;${var-'$'} results in "bad substitution"
(probably due to the changed internal quoting mechanism).
The same with '"' and '`' as values,
for all but the ":+" and "+" form of
parameter expansion.
ulimit" built-in
[8]
-h to check for symbolic links
$SHELL). restricted functionality
even not documented anymore.
cd" fails due to permissions,
perror() is called, "Permission denied".
Otherwise "cd" only knows "bad directory", though.
chdir" reactivated (undocumented)
LC_CTYPE/LC_default added
LC_CTYPE/LC_COLLATE
-L to check for symbolic links
ulimit" is implemented with the 4.2BSD/SVR4-like
getrlimit(2)
cat <<`...`" anymore
(and the backquotes have no special meaning)
[...]"
IFS='\' splits correctly again
migrate" for migrating processes to other "sites".
"setspath" for using different "sites".
"setxvers" for setting an
"experimental version prefix" (in connection with
using "hidden directories").
In contrast to the documentation, "onsite" is not
implemented.
cd"
linked in from libc
TIMEOUT mechanism activated
${var-'$'} and related parameter expansions bugs
(which were introduced with SVR3)
type" returns false on "[...]: not found"
limit" and "unlimit"
as interface to getrlimit(2)
-l to check for symbolic links
-L" for "cd" and "pwd"
added, toggling between using logical or physical pathnames,
i.e., wether navigation along symbolic links is remembered
-L and -h to check
for symbolic links
cd" provides a spell checker
LC_CTYPE/LC_COLLATE
-H and -M to check
for a semaphore or shared memory, respectively
cat <<`...`" anymore
(and the backquotes have no special meaning instead)
umask -S" knows the symbolic notation.
"Bad umask" error message added.
bg fg jobs kill stop suspend")
-m" to switch on/off
job control.
ulimit" now implemented with getrlimit(2),limit"
and "unlimit" instead.
-p" (except on DG/UX, which handles
privileges differently).trap" now accepts symbolic signal names
-h to check for symbolic links.
-L.
-l.
$-) when becoming restricted
via SHELL or argv[0]
env 'A B=1' sh"
("not an identifier").
Such variables are not passed on, though.
chdir" reactivated (probably inherited from SunOS 4
- Sun was involved in SVR4), but except for SunOS 5 not documented
exec>$varying"
TIMEOUT mechanism activated
type" returns false on "[...]: not found"
cat <<`...`" anymore
(and the backquotes are evaluated immediately)
case x in in)" doesn't fail anymore with
syntax error
echo" knows "-n" and
disables backslash escape sequences, if /usr/ucb/
precedes /bin/, /usr/bin/ and
/usr/5bin/ (SunOS4/BSD compatibility).
On "Solaris x86" this is also triggered if
SYSV3 is present in the environment
(labeled "SCO x86 compatibility support").
type" returns false on
"[...] not found"
2>&1 program >/dev/null" doesn't redirect
stderr anymore.
echo a > file1 b > file2"
fixed.
<>" fixed and
documented (used in /etc/inittab f.i.). In fact this was
existent but buggy since v7, search for
IORDW: O_RDWR is lacking.
read -r", "mldmode" and "priv"
umask -S" knows the symbolic notation.
"Bad umask" error message added.
UX:sh: ERROR: ..."
(years after the first definition in the SVID)
foo=`echo $bar` bar=text" results in foo being empty:
"order of evaluation for variable assignments is changed to use
left to right expansion rules."
TIMEOUT mechanism activated
(the unit is seconds in contrast to minutes in previous shell versions)
type" returns false on "[...] not found"
Footnotes for the list above:
| [1] | Naturally, virtually all commercial systems provide a
traditional Bourne shell. Meanwhile, you'll find it at a path
different from /bin/sh on several systems
(e.g., HP-UX 10 ff.) or under the different name bsh
(e.g., on AIX 4 ff. and IRIX 6.4 ff.).
See also various system shells.
No rule without exception: On HP-UX 11i Version 1.5 and ff. the Bourne shell is not shipped anymore. |
| [2] | A Bourne shell not being 8-bit clean shows subtle bugs, e.g., when
using ${b="$a"} with $a containing spaces:
The internal quoting mechanism sets the 8th bit for all characters
due to the doublequotes, and thus $b won't contain real
spaces aymore. This can be demonstrated with
"for i in $b; do echo $i; done"
(but not with "echo $b" because then the 8th bit certainly
gets unset again).
|
| [3] | In the traditional BSD line, the Bourne shell was shipped
until 4.3BSD-Reno (but not anymore with Net/2 and the following 4.4BSDs).
For license reasons it was then substituted with the bourne-compatible,
svr4-like ash by Kenneth Almquist.
|
| [4] | SINIX 5.20 offers three socalled universes: "ucb", "sie"(mens) and "xopen" (aka "att"). These provide shells from 4.2BSD, SystemIII and SVR3, respectively. See some notes about the sinix universes if you are curious. |
| [5] | Most modifications for the Version 8 shell were driven by the motivation for a clean design. Interestingly, the fact that function calls overwrite the positional parameters was not changed. |
| [6] | The Migration Guide
"
System V Environment for Digital UNIX Version 4.0." (560 kB PDF)
claims, that /bin/sh on OSF1/V4 and /V5 is a SVR3.2 shell.
However, it's missing a few characteristic properties of this
shell (modern "$@", "getopts" and the PATH fix).
After all, it seems more likely, that it is a heavily extended SVR2 shell.
|
| [7] | To try the unicode support on HP-UX, you need an according
font and the ability to insert multi-byte characters. I prefer
Thomas Dickey's XFree86 Xterm with Markus Kuhn's fonts.
Set LC_COLLATE and LC_CTYPE after
looking at "locale -a" and also set "stty -istrip cs8".
|
| [8] | On SunOS 4, the "ulimit" built-in is not implemented at all.
getrlimit(2) lists this under BUGS
(but in fact this origins from 4.2BSD).
File size limits are catched with quotas instead, and apparently Sun
didnt't want to add support by getrlimit(2) otherwise.
|
| [9] | If you run an older shell without job control:
Don't forget about nohup(1).
However, note that background jobs are not in a new process group,
which has again a strong influence on signal handling.
|
| [10] | The version on IRIX 5.x ff.
|
| [11] | sh on DG/UX 4.20 knows about the "UX:sh:" message
and seems to originate from between SVR4.0 and SVR4.2. As specific
extensions it provides command line editing and a
"readt" built-in (timing out).
|
See an article from John Mashey in net.unix-wizards ('86). By the way, the Mashey shell from the Programmer's Workbench, about "PWB 1.0", is also archived by TUHS.
See also an article by David Korn ('94) with an interesting second chapter concerning the Bourne shell history.
(The Bourne shell would probably be in much wider interactive use today, if it provided line editing (and a history mechanism). Having the above article in mind, this was (like with ksh originally) probably not done in the hope that these features would move into the terminal driver?)
See manual pages of two main predecessors of the Bourne shell, the "Thompson" and the "Mashey" shell:
< and >.
(comments from Normal Wilson on TUHS list.)
^ and |.
(DMR about this
on his pages
and at
TUHS.)
as well as the
I collected some enlightening notes about the
memory management, i.e., using sbrk(2)
and trapping SIGSEGV.
Meanwhile the early Unix variants have become available in source
under a BSD-like license from SCO, have look at
TUHS.
Usually you will not be able to
easily compile earlier Bourne shells on a modern unix variant, as
it is really oldfashioned C code with wild pointer management, as the
internal memory management crashes the malloc used
in libc nowadays and as it's using an older UNIX API (especially for
directory access). The source is also odd to read without preprocessing
(e.g., it is made "algol-like" with preprocessor macros). Apart from
just running V7 and its shell in an emulator like simh:
Geoff Collyer provides a source package of the V7 shell which should compile on most POSIX systems. He has updated the memory management and directory-access code with parts from his V9 shell. However he has added a few minor modifications, so it's not an original reimplementation.
He has also written "a partial tour through the unix shell", quite important if you want to get busy with the source. It's emphasizing the memory management but also contains general hints.
<http://www.in-ulm.de/~mascheck/bourne/>