Shells Available for Linux

The Bourne Shell

BSD sh (ash)*

GNU bash
From the Shell-Differences FAQ :
In the near beginning there was the Bourne shell /bin/sh (written by S. R. Bourne), it had (and still does) a very strong powerful syntactical language built into it, with all the features that are commonly considered to produce structured programs, it has particularly strong provisions for controlling input and output and in its expression matching facilities. But no matter how strong its input language is, it had one major drawback; it made nearly no concessions to the interactive user (the only real concession being the use of shell functions and these were only added later) and so there was a gap for something better.

The C Shell

BSD csh (or port thereof) csh526.patch*
From the Shell-Differences FAQ:

Along came the people from UCB and the C-shell /bin/csh was born. Into this shell they put several concepts which were new, (the majority of these being job control and aliasing) and managed to produce a shell that was much better for interactive use. But as well as improving the shell for interactive use they also threw out the baby with the bath water and went for a different input language.

The theory behind the change was fairly good, the new input language was to resemble C, the language in which UNIX itself was written, but they made a complete mess of implementing it. Out went the good control of input and output and in came the bugs. The new shell was simply too buggy to produce robust shell scripts and so everybody stayed with the Bourne shell for that, but it was considerably better for interactive use so changed to the C shell, this resulted in the stupid situation where people use a different shell for interactive work than for non-interactive, a situation which a large number of people still find themselves in today.

After csh was let loose on an unsuspecting world various people decided that the bugs really should get fixed, and while they where at it they might as well add some extra features. In came command line editing, TENEX-style completion and several other features. Out went most of the bugs, but did the various UNIX operating system manufacturers start shipping tcsh instead of csh? No, they stuck with the standard C-Shell.

The Korn Shell

pdksh pdksh-4.9.tar.gz pdksh-4.9_bin.tar.gz

From the Shell-Differences FAQ:
Eventually David Korn from AT&T had the bright idea to sort out this mess and the Korn shell /bin/ksh made its appearance. This quite sensibly junked the C shells language and reverted back to the bourne shell language, but it also added in the many features that made the C shell good for interactive work (you could say it was the best of both worlds), on top of this, it also added a some features from other operating. The Korn shell became part of System V but had one major problem; unlike the rest of the UNIX shells it wasn't free, you had to pay AT&T for it.


From the Shell-Differences FAQ:

It was at about this time that the first attempts to standardize UNIX started in the form of the POSIX standard. POSIX specified more or less the System V Bourne Shell (by this time the BSD and System V versions had got slightly different). Later the standard is upgraded, and somehow the new standard managed to look very much like ksh.

Also at about this time the GNU project was underway and they decided that they needed a free shell, they also decided that they wanted to make this new shell POSIX compatible, thus bash (the Bourne again shell) was born. Like the Korn shell, bash was based upon the Bourne shells language and like the Korn shell, it also pinched features from the C shell and other operating systems (in my opinion it put them together better; guess which shell I use), but unlike the Korn shell it is free. Bash was quickly adopted for Linux (where it can be configured to perform just like the Bourne shell), and is the most popular of the free new generation shells.


Since most of you would be familiar with bash, there isn't much to say here...

pdksh, a freeware Korn Shell, is available, although last I heard, bash did better in some Korn Shell compatibilty tests...

A wonderful paper describing why you shouldn't use csh for programming was written by Tom Christiansen , but I can't remember where it lives - he sometimes posts it to as either Csh Programming Considered Harmful or Why Csh Is Not My Favourite Progamming Language.

However, this needn't deter you from using csh or tcsh as an interactive shell (Tom himself uses tcsh I hear...), especially tcsh, which is probably second to zsh in the way of niceties for interactive use.

rc and es

rc rc-1.5betadev-1.tar.Z
From the Shell-Differences FAQ :
Meanwhile faced with the problem of porting the Bourne shell to Plan 9, Tom Duff revolts and writes rc, he publishes a paper on it, and Byron Rakitzis reimplements it under UNIX. Rc ended up smaller, simpler, more regular and in most peoples opinion a much better programmed shell.

(By the way, rc stands for ``Run Commands'', since that's what it does...)

Some example rc code follows, from the EXAMPLES file in the source distribution :

# Use pathprefix filename var1 var2 var3
# returns filename, with leading prefixes (in $var1...) turned into the
# string $var1...
fn pathprefix { p1=() i=() j=() {
    p1=$1 ; shift
    for (i) {
        ~ $p1 $$i $$i^/* && {
            *=`` (/) { echo -n $p1 }
            for (j in `` (/) { echo -n $$i } ) shift
            for (j) p1=$p1 ^ '/' ^ $j
            echo $p1
            return 0
    echo $p1
    return 0
} }



pathprefix /usr/users/rsalz home usr    # --> $home
pathprefix /usr/users/rsalz z           # --> $z/rsalz
pathprefix /usr/users/rsalz/foo z home  # --> $z/rsalz/foo
pathprefix /usr/users/rsalz/foo home    # --> $home/foo

With Paul Haahr, Rakitzis then went on to implement es (Extensible Shell). From a paper written for the 1993 Winter USENIX conference :

In the fall of 1990, one of us (Rakitzis) re-implemented the Plan 9 command interpreter, rc, for use as a Unix shell. Experience with that shell led us to wonder whether a more general approach to the design of shells was possibler, and this paper describes the result of that experimentation. We applied concepts from modern functional programming languages, such as Scheme and ML, to shells, which typically are more concerned with UNIX features than language design. Our shell is both simple and highly programmable. By exposing many of the internals and adopting constructs from functional programming languages, we have created a shell which supports new paradigms for programmers.

(this paper is available from here)

es is functionally based (it even has lambda functions). Almost all standard shell constructs are function calls (eg. pipes, redirection, etc.) - all these primitive function calls can be replaced, for example :

  1. a function to implement an executable path cache (like in bash, csh, tcsh, zsh, etc.).
  2. rewriting '>' to implement the csh 'noclobber' option (don't overwrite existing files).
  3. rewriting '|' to time each element in a pipeline.
  4. rewriting 'cd' to place the current directory in your prompt and/or the title bar of an XTerm window.

You can even rewrite the interpreter loop !

Some example es code, from the EXAMPLES file in the source distribution :

# %whatis in es raises an exception if it fails, rather than
# just signalling an error.  thus, i use catch to handle failures
# when doing path searching like this.

EDITOR = <={ catch @{} { %whatis jed } }
VISUAL = <={
        catch @{
                catch @{} { %whatis jed }
        } {
                %whatis visual

The path cache code :

# path caching
#       this patch caches absolute path names for executables found by
#       %pathsearch.  it emulated the ``hashing'' in recent Bourne shells.
#       fortunately, its implementation does not resemble that of the csh,
#       which scans all directories in $path when the shell starts up.
#       i originally wrote this as an experiment, not intending to use it,
#       but i've kept it around because when all the directories in $path
#       are NFS-mounted (as mine are) and your network is busy, the caching
#       actually makes the system feel faster.

path-cache =
let (search = $fn-%pathsearch)
        fn %pathsearch prog {
                let (what-it-is = <={$search $prog}) {
                        if {~ $what-it-is /*} {
                                path-cache = $path-cache $prog
                                fn-$prog = $what-it-is
                        return $what-it-is
fn recache {
        if {~ $#* 0} {
                * = $path-cache
                path-cache =
        for (i = $*)
                fn-$i =

And lastly, a mechanism for autoloading of shell functions :

# autoloading of shell functions
#       this is a very simple patch to %pathsearch which tries to autoload
#       shell functions from the directory $autoload.  the function foo
#       should be in a file named foo and (since that file is run) should
#       contain the definition of the function, as in
#               fn name args {
#                       body
#               }
#       note that you don't want to put the body alone into the file.
#       imho, this is a big win for es.  other shells have autoloading of
#       shell functions (i've heard that credit for applying the idea to
#       shells goes to Dave Korn), but this is implemented with no extra
#       mechanism inside the shell. 

autoload = ~/bin/es
let (search = $fn-%pathsearch)
        fn %pathsearch prog {
                if {access -f -r $autoload/$prog} {
                        . $autoload/$prog
                        if {!~ $#(fn-$prog) 0} {
                                return $(fn-$prog)
                $search $prog

Both rc and es lack built-in line-editing and history mechanisms, although both can be compiled with GNU's Readline (or the smaller sized freeware editlinelibrary, and they can write their commands to a history file for use with a stand-alone history command (provided in the source directories on their ftp sites as history.tar.Z).

There are mailing lists - send mail to or


The Z Shell
From the Shell-Differences FAQ :
The search for the perfect shell still goes on and the latest entry into this arena is zsh. Zsh was written by Paul Falstad while he was a student a Princeton and is a feature packed shell which has so many features that I don't even think the he even knows all of them.

As was said above, zsh is packed with feeping creatures - most, if not all major features of tcsh, bash, ksh, etc. are present in zsh, and that's not all! Some more features are listed below (courtesy of the zsh faq):

A demo shell function provided with the source allows zsh's multi-line line editor to be used to edit small files. Global aliasing, although potentially dangerous, can be useful.

A trivial example of global aliases :

alias -g /etc/passwd='<(ypcat passwd)'
grep andrew /etc/passwd

As wonderful as all this sounds, the Z Shell is currently in an ``active beta'' development stage (which should sound familiar to Linux users ;-). As of now (3rd of April 1994), it is at version 2.4 beta, patchlevel 309. It's mostly stable, but if you try hard enough you can crash it now and then...

Two mailing lists exist, one for announcements only, the other for discussion of the shell (including fixes for bugs, etc.) - send mail to here, with subscribe zsh-announce or subscribe zsh-list in the mail body.

A Frequently-Asked-Questions list is posted to both mailing lists as well as every month.


Written as an emergency shell to counter the hassles people had trying to upgrade their shared C libraries (eg. ln -fs, this was designed to be linked statically. It has builtin (minimal) versions of some useful commands : The entire list of commands is :
-chgrp -chmod -chown -cmp -cp -dd -echo -ed -grep -kill -ln
-ls -mkdir -mknod -more -mount -mv -printenv -pwd -rm
-rmdir -sync -tar -touch -umount alias cd exec exit help
prompt quit setenv source umask unalias
(the internal versions of commands all start with a dash : it tries running the real one, but if it can't be found it will use the internal one instead)

Not particularly suited to long-term interactive use, but it shouldn't be too hard to hack readline support into it if you're desparate (though this would add quite a bit to the size of the binary - editline might be a better choice of line editor libary...)

Novelty Shells

adsh (The Adventure Shell)
(a different version was reposted to alt.sources and alt.folklore.computers in August 1993)

The Adventure Shell is ideal when you're slightly bored with the mundanity of normal shell life - it turns the shell environment into something resembling an old text adventure game (the type that ran on your super-powerful z80 in the ``good old days'' (tm)), filled with monsters, rooms and things to grab.

As an example :

You have entered /home/andrew.  This room contains:
There are exits labeled:
as well as a passage overhead.
There are shadowy figures in the corner.
->  get zsh.faq
zsh.faq: taken
->  wake cat
You awaken the cat monster:
> #!/bin/sh
>> (
>> cat $*
>> echo currentdevice /PageCount gsgetdeviceprop == flush
>> ) | gs -q -sDEVICE=bit -sOutputFile=/dev/null -r5 - | tail -1
The monster slithers back into the darkness.

When you 'get' a file, it goes into your knapsack ~/.knapsack), and can be dropped in another room (directory)...

Obviously, this shell isn't much use for real work.


This appears to have been somebody's university assignment, and as such is a pretty minimal shell, but may be of use to those looking to write their own shell.

Sources of information