UNIX Unleashed, System Administrator's Edition

- 13 -

Which Shell Is Right for You? Shell Comparison

by John Valley and Sean Drew

Most contemporary versions of UNIX provide three shells--the Bourne and/or POSIX
shell, the C shell, and the Korn shell--as standard equipment. However, there are
many other shells available for use, including, but not limited to: Z shell, TC shell,
RC shell and the Bourne Again shell. Choosing the right shell to use is an important
decision because you will spend considerable time and effort learning to use a shell,
and even more time actually using the shell. The right choice will allow you to benefit
from the many powerful features of UNIX with minimal effort. This chapter is intended
to assist you in choosing a shell by drawing your attention to the specific features
of each shell.

Of course, no one shell is best for all purposes. If you have a choice of shells,
then you need to learn how to choose the right shell for the job.

The shell has three main uses:

1. As a keyboard interface to the operating system

2. As a vehicle for writing scripts for your own personal use\

3. As a programming language to develop new commands for others

Each of these three uses places different demands on you and on the shell you
choose. Furthermore, each of the shells provides a different level of support for
each use. This chapter describes the advantages and disadvantages of some of the
more commonly used shells with respect to the three kinds of tasks you can perform
with a shell.

Interactive Usage

The first point to keep in mind when choosing a shell for interactive use is that
your decision affects no one but yourself. This gives you a great deal of freedom:
you can choose any shell without consideration for the needs and wishes of others.
Only your own needs and preferences matter.

The principal factors that affect your choice of an interactive shell are as follows:

Prior experience. Prior experience can be either a plus or a minus when
choosing a shell. For example, familiarity with the Bourne shell is an advantage
when working with a Bourne shell variant, such as the Korn shell, but something of
a disadvantage when working with the C shell or one of its variants. Don't let prior
experience dissuade you from exploring the benefits of an unfamiliar shell. There
are basically two main syntax styles for shells: Bourne and C. The main members of
the Bourne family are Bourne, Bourne Again, POSIX, Korn, and Z. The main members
of the C shell family are C and TC. Shells such as Z and Bourne Again have varying
degrees of C shell syntax support built in.

Learning. A lamentable fact of life is that as the power and flexibility
of a tool increases, the tool becomes progressively more difficult to learn how to
use. The much-maligned VCR, with its proliferation of convenience features, often
sits with its clock unset as silent testimony. So, too, it is with UNIX shells. There
is a progression of complexity from the Bourne shell, to the C shell, to the Korn
shell, and on to other shells, with each shell adding features and shortcuts to the
previous. The cost of becoming a master of the extra features is extra time spent
learning and practicing. You'll have to judge whether you'll really use those extra
features enough to justify the learning time. Keep in mind that all shells are remarkably
similar and relatively easy to learn at the most basic level. The Bourne shell family
has a much richer (although more cryptic) programming language than the C shell family.
While the C shell's Spartan programming interface is easier to learn, it can be quite
a hindrance for most programming tasks, save for the simplest of scripts.

Command editing. All shells offer features to assist with redisplaying
and reusing previous commands, the Bourne shell being the notable exception. The
extra time savings you can realize from command editing features depends greatly
on how much you use the shell. Generations of UNIX users lived and worked before
shells such as the C shell and Korn shell were invented, demonstrating that the Bourne
shell is eminently usable, just not as convenient for the experienced, well-practiced
user of a shell with some form of command reuse.

Wildcards and shortcuts. Once again, your personal productivity (and general
peace of mind) will be enhanced by a shell that provides you with fast ways to do
common things. Wildcards, command aliases, and completion can save you a great deal
of typing if you enter many UNIX commands in the course of a day.

Portability. If you sit in front of the same terminal every day, use the
same UNIX software and applications for all your work, and rarely, if ever, deal
with an unfamiliar system, then, by all means, choose the best tools that your system
has available. If you need to work with many different computers running different
versions of UNIX, as system and network administrators often must, you may need to
build a repertoire of tools (shell, editor, and so on) that are available on most
or all of the systems you use. Don't forget that being expert with a powerful shell
won't buy you much if that shell isn't available. For some UNIX professionals, knowing
a shell language that's supported on all UNIX systems is more important than any
other consideration.

Table 13.1 rates seven commonly available shells using the preceding criteria,
assigning a rating of 1 for best choice, 2 for acceptable alternative, and 3 for
poor choice.

Table 13.1. Ranking of shells for interactive use.

Shell

Experience

Editing

Shortcuts

Portability

Learning

Bourne

3

3

3

1

1

POSIX

2

1

2

1

2

C

2

2

2

3

2

Korn

1

1

2

2

2

TC

2

1

1

3

3

Bourne Again

2

1

1

2

3

Z

2

1

1

3

3

Bourne Shell

I rated the Bourne shell as your best choice for learning because it is the simplest
of the three to use, with the fewest features to distract you and the fewest syntax
nuances to confuse you. If you won't be spending a lot of time using a command shell
with UNIX, then, by all means, develop some proficiency with the Bourne shell. You'll
be able to do all you need to, and the productivity benefits of the other shells
aren't important for a casual user. Even if you expect to use a UNIX command shell
frequently, you might need to limit your study to the Bourne shell if you need to
become effective quickly.

I rated the Bourne shell as lowest in the productivity categories because it has
no command editor and only minimal shortcut facilities. If you have the time and
expertise to invest in developing your own shell scripts, you can compensate for
many of the Bourne shell deficiencies, as many shell power users did in the years
before other shells were invented. Even so, the lack of command editing and command
history facilities means you'll spend a lot of time retyping and repairing commands.
For intensive keyboard use, the Bourne shell is the worst of the three. If you have
any other shell, you'll prefer it over the Bourne shell.

Shells like the C shell and the Korn shell were invented precisely because of
the Bourne shell's low productivity rating. The new shells were targeted specifically
to creating a keyboard environment that would be friendlier and easier to use than
the Bourne shell, and they are here today only because most people agree that they're
better.

Portability concerns, however, might steer you toward the Bourne shell despite
its poor productivity rating. Being the oldest of the three shells (it was written
for the very earliest versions of UNIX), the Bourne shell is available virtually
everywhere. If you can get your job done using the Bourne shell, you can do it at
the terminal of virtually any machine anywhere. This is not the case for shells such
as the C and Korn shells, which are available only with particular vendors' systems
or with current UNIX releases.

I gave the Bourne shell a rating of 3 for prior experience because prior experience
using the Bourne shell is no reason to continue using it. You can immediately use
any of Bourne shell variants, such as the Korn or Bourne Again shell, with no additional
study and no surprises, and you can gradually enhance your keyboard skills as you
pick up the new shell extensions. If you know the Bourne shell and have access to
a Bourne shell variant, you have no reason not to use a variant.

The Bourne shell is provided by your UNIX vendor, although it is being phased
out in favor of the POSIX shell. For example, on HP-UX 10.X systems, the Bourne shell
now resides in /usr/old/bin, and the POSIX shell is now in the traditional
/usr/bin.

POSIX Shell

If you graft on some interactive productivity enhancements onto the Bourne shell,
the result is the POSIX (Portable Operating System Interface) shell. The POSIX shell
is very similar to the Korn shell in terms of the interactive features provided,
right down to the keystroke in most cases. The Korn shell is not standardized, so
there are annoying differences between various vendor's versions; the POSIX shell
attempts to raise the bar for a universally available shell.

The current POSIX shells are based on POSIX.2 of the IEEE POSIX Shell and Tools
specification (IEEE Working Group 1003.2). The POSIX shell is a superset of the Bourne
shell.

I rated the POSIX shell as a 2 for learning because it has many more interactive
features than the Bourne shell, but fewer features than the Bourne Again or Z shells.
The POSIX shell rates a 1 in the area of command editing, providing both vi
and emacs command support. The command-line editing feature set supported
by the POSIX shell is not as rich as TC, Bourne Again, or Z shell, but is more than
adequate for most tasks.

The POSIX shell offers many shortcuts, such as aliases, cd path searches,
filename completion and job control. The shortcut features rated a 2, because the
POSIX shell has much more than the Bourne shell, but less than the TC, Bourne Again,
and Z shells. The POSIX shell receives high marks for portability, as it should soon
be available on most common UNIX versions.

The POSIX shell rated a 2 in the experience category, because if you know the
POSIX shell and are satisfied with its feature set, there isn't a large set of compelling
reasons to switch to another shell. The Bourne Again and Z shells offer more features,
and support most of the POSIX features, so if default availability is not an issue
and you need the extra features, switching should be a fairly painless task.

The POSIX shell should be provided by your UNIX vendor as part of the default
set of shells.

C Shell

The C shell rates a 2 for learning difficulty, based simply on the total amount
of material available to learn. The C shell falls on the low end of the shell spectrum
in terms of the number and complexity of its facilities. Make no mistake--the C shell
can be tricky to use, and some of its features are rather poorly documented. Becoming
comfortable and proficient with the C shell takes time, practice, and a certain amount
of inventive experimentation. When compared to the Bourne shell only on the basis
of common features, the C shell is no more complex, just different.

The C shell rates a passing nod for command editing because it doesn't really
have a command editing feature. The C shell's history substitution mechanism is somewhat
complicated to learn and can be clumsy to use at times, but it is much better than
nothing at all. Just having a command history and history substitution mechanism
is an improvement over the Bourne shell. But the C Shell is a poor comparison to
the simple and easy (if your know vi or emacs) command editing
of the Korn, POSIX, Bourne Again, TC or Z shells.

For example, with the Korn shell, you can reuse a previously entered command,
even modify it, just by recalling it (Esc-k if you're using the vi option)
and overtyping the part you want to modify. With the C shell, you can also reuse
a previous command, but you have five different forms for specifying the command
name (!!, !11, !-5, !vi, or !?vi), additional
forms for selecting the command's arguments (:0, :^, :3-5,
:-4, :*, to name a few), and additional modifiers for changing
the selected argument (:h, :s/old/new/, and so forth). Even remembering
the syntax of command substitution is difficult, not to mention using it. The history
substitution mechanism also provides no access to multi-line commands such as foreach.
The lack of access to multi-line commands can be frustrating; you have to retype
all the enclosed commands. History substitutions, once you have learned the syntax,
can be much faster than editing in many cases, because fewer keystrokes are required.
However, there is no substitute for a good command-line editor. The TC, Bourne Again,
and Z shells support all of the C shell history substitutions and provide
command-line editing.

On the other hand, if you like to use wildcards, you'll find that the C shell
wildcard extensions for filenames are easier to use--they require less typing and
have a simpler syntax--than the Korn shell wildcard extensions. In addition to wildcards,
csh provides command and filename completion with a single keystroke. Also,
its cd command is a little more flexible. The pushd, popd,
and dirs commands are not directly supported by some shells, such as the
Korn and POSIX shells (although they can be implemented in those shells by the use
of aliases and command functions). Altogether, the C shell rates well in terms of
keyboard shortcuts available, perhaps in compensation for its only moderately successful
command editing. Depending on your personal mental bent, you might find the C shell
very productive. We have seen that those already familiar with the C shell have in
the past not been driven away in droves by the Korn and other shells.

For portability considerations, the C shell ranks at the bottom, simply because
it's a unique shell language. If you know only the C shell, and the particular system
you're using doesn't have it, you're out of luck. A C shell user almost always feels
all thumbs when forced to work with the Bourne shell, unless she is bilingual and
knows the vagaries and peculiarities of both.

The C shell gets a 2 for prior experience. If you already know the C shell, the
TC shell is a good candidate for a switch. The TC shell provides a command-line editor
and other nifty shortcuts and is probably compatible with your current C shell version.
On the other hand, staying with a C shell variant can be limiting because there are
many more shells in the Bourne family tree. Unless you feel quite comfortable with
the C shell's history substitution feature and use it extensively to repair and reuse
commands, you might find another shell's command editing capability well worth the
time and effort to make a switch. Anyone accustomed to using the shell's command
editing capability feels unfairly treated when deprived of it--it's that good of
a feature. If you haven't already experimented with the Korn, TC, Bourne Again, or
Z shell and you have the chance, I would strongly recommend spending a modest amount
of time gaining enough familiarity with one of these shells to make an informed choice.
You might be surprised and choose a different shell.

Altogether, the C shell is a creditable interactive environment with many advantages
over its predecessor, the Bourne shell. Personal preference has to play a role in
your choice here. However, if you're new to UNIX, the C shell is probably not the
best place for you to start.

The C shell should be provided by your UNIX vendor as part of the default set
of shells.

Korn Shell

In terms of time and effort required to master it, the Korn shell falls in the
middle of the shell spectrum. That's not because it's poorly designed or poorly documented,
but merely because it has more complex features than the Bourne and C shells. Of
course, you don't have to learn everything before you can begin using the Korn shell.

The Korn shell's command editor interface enables the quick, effortless correction
of typing errors, plus easy recall and reuse of command history. The reuse of multi-line
commands is still a bit on the awkward side, as all lines are concatenated together
on line, with control characters representing newlines.

On the down side, the Korn shell provides equivalents for the C shell's wildcard
extensions, but with a complicated syntax that makes the extensions hard to remember
and hard to use. You can have the pushd, popd directory interface,
but only if you or someone you know supplies the command aliases and functions to
implement them. The ability to use a variable name as an argument to cd
would have been nice. The Korn shell's command aliasing and job control facilities
are nearly identical to those of the C shell. The Korn shell does not provide command
completion but does provide filename completion. Unlike most shells, two keystrokes
are required to complete filenames. From the point of view of keyboard use, the Korn
shell stands out over the C shell mainly because of its command editing feature.
In other respects, its main advantage is that it provides many of the C shell extensions
in a shell environment compatible with the Bourne shell; if Bourne shell compatibility
doesn't matter to you, then the Korn shell might not matter either.

Speaking of Bourne shell compatibility, the Korn shell rates a close second to
the Bourne and POSIX shells for portability. If you know the Korn shell language,
you already know the Bourne shell, because ksh is really a superset of sh
syntax. If you're familiar with the Korn shell, you can work reasonably effectively
with any system having either the Bourne or Korn shells, which amounts to virtually
one hundred percent of the existing UNIX computing environments.

Finally, in terms of the impact of prior experience, the Korn shell gets a rating
of 2. If you know the Bourne shell, you'll probably want to beef up your knowledge
by adding the extensions of the Korn shell and switching your login shell to ksh.
If you already know ksh, you'll probably stick with it, unless you are tempted
by some of the extra features of bash or zsh. If you know csh,
the advantages of ksh may not be enough to compel you to switch.

If you're a first-time UNIX user, the Korn shell is a good shell for you to start
with. The complexities of the command editing feature will probably not slow you
down much; you'll probably use the feature so heavily that the command editing syntax
will become second nature to you before very long.

The Korn shell should be provided by your UNIX vendor as part of the default set
of shells.

TC Shell

The TC shell can be thought of the next generation C shell. The TC shell supports
all of the C shell syntax and adds powerful command-line editing including: spell
checking for filenames and user IDs, additional completions (hostnames, variable
names, aliases, and so on) and expansions (variable names, filenames). There are
many other features too numerous to mention here.

The TC shell rates a 3 in the learning category because of the wealth of features
to learn as well as the complexity of using/configuring some of the features. For
example, the TC shell offers programmable completion, which is convenient to use
but difficult to program. Fortunately, the TC shell provides several pre-programmed
completions straight out of the box.

The TC shell provides an emacs or vi command-line editor. Unlike
the Korn and POSIX shell, the emacs style of incremental searching is available.
These features give the TC a 1 in the editing arena. However, room for improvement
exists for multi-line commands, such as foreach, which still do not have
the loop contents available in the history editor as do the POSIX, Korn, Bash and
Z shell command-line editors.

The TC shell is chock full of shortcuts and rates a 1, only the Z shell has more
shortcuts available. The TC rates low in portability because it is not available
on all systems and is not generally a shell shipped by vendors. Because there is
only one source for the TC shell, however, it is the same on all systems, aside from
release differences.

As far as prior experience is concerned, if you know the C shell, the TC shell
is fairly simple to pick up. In fact, it will read your .cshrc file without
modifications. You can incrementally pick up the advanced features as needed. So
tcsh is a good shell to switch to if you are a C shell user. The TC shell
does not rate a 1 in the experience category because it is not Bourne compatible,
so learning the TC shell would be hard for users of most other shells.

The TC shell is not generally provided as a standard shell; however, many systems
have the TC shell installed. If your system does not have tcsh installed,
check http://www.primate.wisc.edu/software/csh-tcsh-book
for information on source and pre-compiled binaries. The previous URL also presents
a wealth of information about the TC shell, including man pages, books,
and supporting software. Should that URL fail, try your favorite WWW search engine
for the keyword tcsh.

Bourne Again Shell

The Bourne Again shell is the GNU project's shell and is POSIX-compatible. The
Bourne Again (bash) shell can be thought of as the next generation Korn
shell, as bash is basically a superset of the 1988 version Korn shell, with
many of the Korn shell 1993 features. The Bourne Again shell also offers good support
for many C shell features, in order to help us C shell junkies feel at home, including:
history substitutions using the ! operator, >& output redirection,
{} wildcards, and the source command.

The Bourne Again shell has a great deal to offer; in fact, the current man
page is 55 pages long. The large number of features does not make for an easy time
to become a bash master, so a rating of 3 in the learning arena was awarded.
However, don't be misled into thinking that the Bourne Again shell is overly difficult
to learn, and if you choose not to learn all the features, you can still be quite
productive.

The command-line editing of multi-line commands is better than POSIX, Korn, and
TC shell. Each line shows up as a separate entry in the command history, and as a
result, it is a little easier to reuse portions of a command, but the separate entries
make it difficult to easily reuse the entire command. However, bash offers
a shell variable, command_oriented_history, which, when set, places the
commands on one history line separated by semi-colons (;).

Bourne Again rates well with shortcut features a directory stack with more features
than the C shell, such as the ability to display individual members of the directory
stack. The Bourne Again shell offers more completions and expansions on the command-line
than the C, POSIX, and Korn shells.

bash is something of a conundrum when it comes to portability, I gave
it the benefit of the doubt and assigned it a 1, because you can have the Bourne
Again shell emulate the POSIX shell. In this mode, what you do can easily be replicated
in the POSIX shell. On the other hand, bash is not universally available,
and you need to be careful what features you rely on if portability is of concern
to you.

The experience rating for bash is also a 1. If you use a shell from the
Bourne family, switching to bash will be easy and likely provide you with
more features than your current shell. If you are accustomed to a C shell derivative,
the Bourne Again shell has enough C shell syntax to make the transition relatively
painless. To even further reduce the pain, the Bourne Again shell provides a handy
script for translating your C shell aliases to the Bourne Again syntax, as well as
making semantic substitutions (for instance, $PWD for $cwd). The
bash FAQ (Frequently Asked Questions) even has tips on how to emulate common
C shell features, such as :r replacements.

The Bourne Again shell is not generally provided as a standard shell from most
UNIX vendors, however, many systems have bash installed. In fact, it is
the standard shell for Linux systems. The CD included with this book has a version
of bash on it. If you wish to locate additional information about source
and binary locations, look in the bash FAQ , which can be found at the URL
ftp://slc2.ins.cwru.edu/pub/bash/FAQ.
Failing that, try your favorite WWW search engine for the keywords Bourne Again
or bash FAQ.

Z Shell

The Z shell is the ultimate shell for feature hungry users. If you can think of
something that a shell ought to do, the Z shell probably does it. All that power
comes at a price: for example, on HP-UX 10.01, the zsh executable is nearly
four times larger than the ksh (Korn shell) executable and almost three
time larger than the sh executable (Bourne shell).

I don't think anyone knows all the features of the Z shell, not even the original
author, Paul Falstad. Learning even half of the features would be quite an accomplishment,
so a rating of 3 was given. However, this does not imply that the Z shell is poorly
implemented, designed, or documented; this is strictly a bulk of features issue.

When it comes to command-line editing, Z shell stands head and shoulders over
any shell reviewed in this chapter. Z shell handles multi-line commands the best
out of all the shells, in my opinion. Each command is an editable buffer unto itself,
which makes for easy editing of the command and easy reuse of the entire command,
and it retains the original visual look of the command. Z shell has the most completions
and expansions. Access to expansion is also the most intuitive. For example, the
first press of the Tab key while typing a variable name will complete the variable
name, the next Tab will expand the variable's value into the command-line (assuming
no ambiguities in the completion). Both bash and tcsh require a
separate editor command to expand the variables values (in bashemacs
mode, Esc-$ will expand the variable). Z shell supports programmable completions
that can even further help with command-line editing. For example, you can program
the cd command to use only directories for completions or expansions. Z
shell offers spelling correction for pathnames and user IDs. All these features make
for a rating of 1 in the editing category.

Z shell receives a 1 and is number 1 when it comes to shortcuts. For example,
suppose you have two developers working on a set of files for a project and you want
to determine what files will need merging. In order to do that, you need to see which
files the two developers have in common in their work directories. Let us further
assume you wish to place that list of common files into a file for editing with vi.
The edited list contains the candidates for merging. Suppose you are using the C
shell (have to pick worst case scenario for illustration). You could use a foreach
loop with an if (-e filename) to test for file existence and echo
the filename, but the C shell does not allow redirection from the looping constructs.
Creating a temporary script is a pain, so it's best to use the UNIX comm
command (comm selects or rejects lines common to two sorted files). The
following is a sample C shell session, using #'s for comments.

Enter the Z shell and the process substitution syntax of =(). Process
substitution removes the headache of temporary files, as can be seen from the following
Z shell session, which accomplishes the same task as above.

Process substitution automatically creates a temporary file for you, places the
input in the temporary file, and then passes the name of the temporary file to the
command that needs to process it.

Other nifty Z shell shortcuts include:

Recursive directory searches (ls **/file).

Easy teeing via multiple redirects (ls >file1 >file2).

autocd option that enables directory changes without using cd,
so cd dirname and dirname are equivalent commands.

Null command shorthands. < file is equivalent to more <file,
> file is the same as cat >file, and >> file
is identical to cat >>file.

Shell variable editing with the vared built-in command.

Others to numerous to mention.

Portability is the Z shell's only Achilles heel. The Z shell is not found on as
many systems as most other shells. To ease this, the Z shell can emulate the Korn,
C, or POSIX shell. A rating of 3 was given for portability.

Z shell also shines in the experience category. No matter what shell you know,
switching to Z shell is not too tough. Even if you are a C shell junkie, and I am,
then the various CSH_JUNKIE options can help you out until you have been
properly weaned. The Z shell has support for the most C shell features of any non-C-shell
shell, including: ^^ quick substitution, foreach, and pushd/popd.
With the various shell emulation switches, Bourne, Korn, and POSIX users can also
feel right at home. Save for the portability issue, it is very hard to not really
like the Z shell. As the name implies, Z shell is the last shell you will ever need.

The Z shell is not provided as a standard shell by UNIX vendors, and zsh
is not as ubiquitous as some of the other shells. If your system does not have zsh
installed, check http://www.mal.com/zsh/FAQ/toc.html
or http://www.mal.com/zsh/zsh_home.shtml
for information on source and pre-compiled binaries. The previous URLs also provide
other information about the Z shell, including man pages. Should the URLs
fail you, try your favorite WWW search engine for the keyword zsh.

Interactive Shell Feature Comparison

Table 13.2 describes some of the interactive shell features that are not available
in all shells for comparison purposes. The features that all shells have in common
are not listed (for instance, use of * as a wildcard, search path variable
for executables, ability to get and set environment variables, and so on). Many of
these features could actually be used in scripts, but because the features listed
are used primarily in interactive sessions, they are listed in Table 13.2.

Some of the features mention expansion or completion. In Table 13.2, expansion
refers to the substitution of the value represented by a token on the command-line.
For example, the command-line token *.star could be expanded to dark.star
dwarf.star ura.star (assuming that the previous three files were all that matched
the wildcard expression *.star). If the variable $LOGNAME were
expanded on my command-line, the variable would be replaced with the token sdrew.
Completion refers to the feature of partially typing a name and having the shell
complete the rest of the name on your behalf. For example if you had typed $DIS
on the command-line, using completion, the shell might have typed in PLAY
for you, thus completing the variable name for you with an end result of $DISPLAY
on your command-line.

Table 13.2. Nonportable shell features--Interactive.

Feature

sh

csh

ksh

tcsh

bash

zsh

Aliases

POSIX

X

X

X

X

X

Alias completion

-

-

-

X

X

X

Aliases take arguments

-

X

-

X

-

-

Automatically list choices for ambiguous completions

-

-

-

X

X

X

cd path searches

POSIX

X

X

X

X

X

Command aliases

POSIX

X

X

X

X

X

Command editing (emacs)

POSIX

-

X

X

X

X

Command editing (vi)

POSIX

-

X

X

X

X

Command completion

-

X

-

X

X

X

Built-in command completion

-

-

-

X

X

X

Command documentation being typed

-

-

-

X

-

-

Command history

POSIX

X

X

X

X

X

Command history appending

POSIX

-

X

-

X

-

Co-process support

POSIX

-

X

-

-

X

History substitution

-

X

-

X

X

X

History expansion

-

-

-

X

X

X

Filename completion

POSIX

X

X

X

X

X

Filename expansion

POSIX

-

X

X

-

X

Function completion

-

-

-

-

X

X

Hostname completion

-

-

-

-

X

X

Incremental history searching

-

-

-

X

X

X

Job control (bg, fg, ...)

POSIX

X

X

X

X

X

Log in/out watching

-

-

-

X

-

X

Multi-prompt commands in history buffer

POSIX

-

X

-

X

X

notify shell built-in

POSIX

X

-

X

X

-

One key completion

-

X

-

X

X

X

Programmable completion

-

-

-

X

-

X

pushd, popd commands and/or other directory stack commands

-

X

-

X

X

X

Recursive command-line scans

POSIX

X

-

X

X

-

Spelling correction for user ids, commands and filenames

-

-

-

X

-

X

Substring selectors :x

-

X

-

X

X

X

Variable completion

-

-

-

X

X

X

Variable expansion

-

-

-

X

X

X

Variable editing

-

-

-

-

-

X

*(...) wildcards

POSIX

-

X

-

-

X

$(...) command expression

POSIX

-

X

-

X

X

{...} wildcards

-

X

-

X

X

X

NOTE: The sh
column represents both the Bourne and POSIX shells. If a feature is specific only
to one shell, then that shell's name will appear in the column as opposed to an X.
In short, - means neither shell, X means both shells, Bourne
means just the Bourne shell and POSIX means just the POSIX shell.

Shell Scripts for Personal Use

If you develop any shell scripts for your personal use, you'll probably want to
write them in the same shell language you use for interactive commands. As is the
case for interactive use, the language you use for personal scripts is largely a
matter of personal choice.

Whether you use a C shell variant or a Bourne shell variant at the keyboard, you
might want to consider using the Bourne shell language for shell scripts, for a couple
of reasons. First, personal shell scripts don't always stay personal; they have a
way of evolving over time and gradually floating from one user to another until the
good ones become de facto installation standards. As you'll learn in the section
titled "Shell Scripts for Public Consumption," writing shell scripts in
any language but the Bourne shell is somewhat risky because you limit the machine
environments and users who can use your script.

Second, the C shell variants, while chock full of excellent interactive features,
are sadly lacking in programming features. The chief drawback of C shell variants
is the lack of shell functions (perhaps it is time for the C++ shell). The lack of
shell functions greatly inhibits structured programming. Any function must either
be a separate file or an alias. Aliases can be difficult or impossible to write for
more complex tasks. The C shell variants also do not have parameter substitution,
nor nearly as many variable and file tests. Take it from someone who learned the
hard way, when it comes to C shell programming, just say no. Of course, for
truly trivial scripts containing just a few commands that you use principally as
an extended command abbreviation, portability concerns are not an issue.

Writing short, simple shell scripts to automate common tasks is a good habit and
a good UNIX skill. To get the full benefit of the UNIX shells, you almost have to
develop some script writing capability. This will happen most naturally if you write
personal scripts in the same language that you use at the keyboard.

For purposes of comparison, Table 13.3 describes shell features used for programming
that are not available in all shells. While the features listed here tend to be used
mostly in scripts as opposed to interactive sessions, there is nothing preventing
these features from being used interactively.

Table 13.3. Nonportable shell features--Programming.

Feature

sh

csh

ksh

tcsh

bash

zsh

Arithmetic expressions

POSIX

X

X

X

X

X

Array variables

POSIX

X

X

X

X

X

Assignment id=string

X

-

X

-

X

X

case statement

X

-

X

-

X

X

clobber option

POSIX

X

X

X

X

X

echo -n option

-

X

-

X

X

X

for statement

X

-

X

-

X

X

export command

X

-

X

-

X

X

foreach statement

-

X

-

X

-

X

getopts built-in command

POSIX

-

X

-

X

X

glob command

-

X

-

X

-

-

Hash table problems, rehash and unhash commands

-

X

-

X

-

-

let command

POSIX

-

X

-

X

X

limit, unlimit commands

-

X

-

X

-

X

nice shell built-in

-

X

-

X

-

-

nohup shell built-in

-

X

-

X

-

-

onintr command

-

X

-

X

-

-

print command

POSIX

-

X

-

X

X

Redirection from iterative statements

X

-

X

-

X

X

RANDOM shell variable

POSIX

-

X

-

X

X

repeat shell built-in

-

X

-

X

-

X

select statement

POSIX

-

X

-

X

X

setenv, unsetenv commands

-

X

-

X

-

-

SHELL variable specifies command to execute scripts

-

X

-

X

-

-

switch statement

-

X

-

X

-

-

until statement

X

-

X

-

X

X

set -x

X

-

X

-

X

X

set optionname

-

X

-

X

X

X

Shell functions

X

-

X

-

X

X

trap command

X

-

X

-

X

X

typeset command

POSIX

-

X

-

X

X

ulimit command

X

-

X

-

X

X

Undefined variable is an error

-

X

-

X

-

-

! special character

-

X

-

X

X

X

@ command

-

X

-

X

-

-

>& redirection

-

X

-

X

X

X

Shell Scripts for Public Consumption

Shell scripts developed for public consumption, should be designed for enduring
portability. Shell scripts developed for public use are almost always written in
the Bourne shell language. Although there is a tendency today to write such scripts
in the Korn shell language, people who do so realize they're taking a risk, albeit
a modest one.

Some versions of UNIX allow you to specify the shell interpreter to use for a
given script file by embedding a special command as the first line of the script:
#! /bin/sh as the first line of a script would, on most modern UNIX systems,
force the use of the Bourne shell to execute the script file. This is a handy device
to allow you to develop scripts in the shell language of your choice, while also
allowing users to avail themselves of the script regardless of their choice of an
interactive shell. However, the #! device is not available on all versions
of UNIX.

Shell scripts written in something other than the Bourne or POSIX shell require
the operating system to include the corresponding shell. For example, the C shell
or the Korn shell require that either csh or ksh be installed.
Not all systems meet this requirement, and if portability among several platforms
or between current and future platforms is a consideration (that is, if you're writing
a script to be used by anyone anywhere, both now and years from now), common sense
and reasonable prudence dictate that you avoid non-Bourne shell syntax constructs
in your script. If you write scripts in the POSIX shell and avoid any of the new
built-in commands, such as select, your scripts should be very portable.
The main incompatibility between the Bourne and POSIX shells, assuming that only
Bourne syntax is used, is the result of an old Bourne shell feature. The command-line
arguments are corrupted once a function is called from a script in the Bourne shell;
not so with the POSIX shell. Always follow the practice of saving off needed command-line
arguments ($1, $2É). Saving command-line variables in other
variables will make your scripts more readable as well as more portable.

True portability also limits your use of UNIX commands and command options inside
your shell script. Some versions of UNIX, especially the implementation by IBM, offer
many new command options on many commands, leading the unwary into developing shell
scripts that can run only under the IBM implementation of UNIX. Other versions of
UNIX, such as ULTRIX and XENIX, support only the old-fashioned command library, along
with some local peculiarities. If you're truly interested in developing portable
programs and shell scripts, you should make use of the POSIX and X/Open compatibility
guidelines, which describe only commands and command options that are generally available
on most UNIX operating system implementations.

Even the dialect of the Bourne shell you use can be a portability consideration.
For example, on ULTRIX systems, the command sh supplies only UNIX Version
7 functionality; you have to invoke the command sh5 to run a System V compatible
Bourne shell. With the advent of POSIX, and vendors wishing to be POSIX-compliant,
these issues should lessen over time. The POSIX.2 standard requires a POSIX-compliant
system to run the POSIX shell when the UNIX command sh is specified.

Because perfect portability is, like Scotty's transporter, simply not obtainable
in the twentieth century, a further application of common sense dictates that the
level of effort you invest in portable programming be suitable to the job at hand.
You might want to adopt guidelines something like the following:

For really important projects, choose any shell language (or other tool) you
want--your choice simply becomes another requirement for installation and use of
the system. (Don't forget to tell your user community of such requirements.)

If your shell script might enter the public domain, restrict yourself to the
Bourne shell language, and assume a System V Release 1 environment. This provides
you with a great many tools but also suits your application to the vast majority
of contemporary UNIX installations.

If your shell script is targeted for use at your local installation, choose either
the Bourne, POSIX, or Korn shell language. Use the Korn shell if you feel you need
its features, but do not use it gratuitously or casually. The odds are heavily in
your favor that any future operating system releases or vendor changes will still
support your shell script.

If your project must meet certain stated compatibility goals (for example, you
must support the HP-UX and SunOS machines running at three offices in two different
countries), then by all means adjust your project to meet those goals. There will
still be aspects of your project where no stated goals apply. In those cases, choose
the level of generality and portability that you (or your project timetable) can
afford.

In all other cases, choose the tools and languages that you feel permit the most
effective, trouble-free, user friendly implementation you can devise, and don't forget
to maximize your own productivity and effectiveness.

Summary

Selecting a shell for use at the keyboard, as an interactive command-line processor,
is a relatively straightforward task once you realize that your choice does not affect
others. If you are new to UNIX, you should consider using the POSIX shell because
its built-in command editing feature can significantly increase productivity. Users
accustomed to the C shell are also advised to investigate the POSIX shell, for the
same reason.

Familiarity with the Bourne and POSIX shells and their capabilities and restrictions
are essential for individuals who must work with a variety of UNIX systems or with
the general UNIX public. Bourne is the only shell that is universally available under
all implementations of the UNIX operating system, and the POSIX shell is becoming
nearly as ubiquitous.

For daily keyboard use, any shell but the Bourne shell is a good choice. The Bourne
shell is not a good choice when other shells are available. The Bourne shell has
a decided lack of interactive features, with command history and command editing
being especially productivity degrading.

Choosing a shell for writing scripts is, however, a different matter entirely.

The newer shells offer tools to the script writer that are hard to do without,
such as simplified syntax for command substitutions, array variables, variable arithmetic
and expressions, and better structured commands such as select. Because
these tools are so helpful, they should be used for any work intended only for personal
consumption. They should also be preferred for location-specific projects, where
the environment can be predicted reasonably accurately. However, for shell scripts
claiming a wider audience, the Bourne shell still serves as the lingua franca
of the UNIX world and will for some time to come.

The script writer who cannot anticipate the hardware and software environment
must consider the choice of commands and command options used in the script as well
as the shell language. A few environments offer a wider variety of commands and command
options than most, and some UNIX versions omit some of the conventional UNIX runtime
features. For most purposes, an implementation compatible with UNIX System V Release
1 can be considered as a minimum portability base. In situations where portability
is especially important, the POSIX and X/Open standards should be consulted as guides
to available operating system features and capabilities, rather than the vendor's
manuals.

Shell programming can be as simple or as complex as you wish it to be. Shells
are sufficiently sophisticated programming tools and can permit the implementation
of efficient, production quality software. In fact, shell scripts can be used instead
of a more traditional third generation language, such as the C or C++ programming
languages. In fact, I once replaced a 500-line C++ program with a 4-line shell script.
The use of shell scripts has also become popular as a prototyping and rapid development
method.

It would seem that, while one shell can be chosen for customary use at the keyboard,
the choice of a shell environment for writing shell scripts needs to be reconsidered
for each project.