TOC BACK FORWARD HOME

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:

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 bash emacs 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.

% (cd ~harryman/cxxsource/proj1;ls *.{cc,hh}) > /tmp/davesFiles  
#darn, need to name a temp file
% (cd ~robic/dominic/proj1;ls *.{cc,hh}) > /tmp/mattsFiles       
#darn, need to name another temp file
% comm -12 /tmp/davesFiles  /tmp/mattsFiles  > needMerge         
#show what is in both files
% rm /tmp/davesFiles  /tmp/mattsFiles                            
#kill those pesky temporary files
% vi needMerge                                                   
#vi at last!

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.

% vi =(comm -12 =(cd ~harryman/cxxsource/proj1;ls *.
{cc,hh}) =(cd ~robic/dominic/proj1;ls *.{cc,hh}))

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:

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:

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.

TOCBACKFORWARDHOME


©Copyright, Macmillan Computer Publishing. All rights reserved.