Book HomeRunning LinuxSearch this book

13.3. Shell Programming

In the section "Section 4.5, "Shells"" in Chapter 4, "Basic Unix Commands and Concepts", we discussed the various shells available for Linux, but something should be said about them in terms of programming. The differences come through most clearly when it comes to writing shell scripts. The Bourne shell and C shell command languages are slightly different, but the distinction is not obvious with most normal interactive use. In fact, many of the distinctions arise only when you attempt to use bizarre, little-known features of either shell, such as word substitution or some of the more oblique parameter expansion functions.

The most notable difference between Bourne and C shells is the form of the various flow-control structures, including if …then and while loops. In the Bourne shell, an if …then takes the form:

if list 
then 
  commands 
elif list 
then 
  commands 
else 
  commands 
fi
where list is just a sequence of commands (more generally called "pipelines") to be used as the conditional expression for the if and elif (short for "else if") commands. The conditional is considered to be true if the exit status of the list is zero (unlike Boolean expressions in C, in shell terminology an exit status of zero indicates successful completion). The commands enclosed in the conditionals are simply commands to execute if the appropriate list is true. The then after each list must be on a new line to distinguish it from the list itself; alternately, you can terminate the list with a ;. The same holds true for the commands.

An example is:

if [ "$PS1" ]; then 
  PS1="\h:\w% " 
fi
This sequence checks to see whether the shell is a login shell (that is, whether the prompt variable PS1 is set) and if so, resets the prompt to \h:\w%, which is a prompt expansion standing for the hostname followed by the current working directory. For example:
loomer:/home/loomer/mdw%

The […] conditional appearing after the if is a bash built-in command, shorthand for test. The test command and its abbreviated equivalent provide a convenient mechanism for testing values of shell variables, string equivalence, and so forth. Instead of using […], you could call any set of commands after the if, as long as the last command's exit value indicates the value of the conditional.

Under tcsh, an if …then compound statement looks like the following:

if (expression) then 
  commands 
else if (expression) then 
  commands 
else  
  commands 
endif
The difference here is that the expression after the if is an arithmetic or logical expression evaluated internally by tcsh, while with bash the conditional expression is a command, and the expression returns true or false based on the command's exit status. Within bash, using test or […] is similar to an arithmetic expression as used in tcsh.

With tcsh, however, if you wish to run external commands within the expression, you must enclose the command in braces: {command}.

The equivalent of the previous bash sequence in tcsh is:

if ($?prompt) then 
  set prompt="%m:%/%% " 
endif
where tcsh 's own prompt special characters have been used. As you can see, tcsh boasts a command syntax similar to the C language, and expressions are arithmetically and logically oriented. In bash, however, almost everything is an actual command, and expressions are evaluated in terms of exit status values. There are analogous features in either shell, but the approach is slightly different.

A similar change exists with the while loop. In bash, this takes the form:

while list 
do 
  commands 
done
You can negate the effect by replacing the word while with until. Again, list is just a command pipeline to be executed, and the exit status determines the result (zero for success and nonzero for failure). Under tcsh the loop looks like:
while (expression) 
  commands 
end
where expression is a logical expression to be evaluated within tcsh.

This example should be enough to get a head start on understanding the overall differences of shell scripts under bash and tcsh. We encourage you to read the bash and tcsh manual pages (although they barely serve as a tutorial--more as a reference) and Info pages, if you have them available. Various books and tutorials on using these two shells are available as well; in fact, any book on shell programming will do, and you can interpolate the advanced features of bash and tcsh over the standard Bourne and C shells using the manual pages. Learning the bash Shell by Cameron Newham and Bill Rosenblatt and Using csh and tcsh by Paul DuBois are also good investments.



Library Navigation Links

Copyright © 2001 O'Reilly & Associates. All rights reserved.