Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [76]

By Root 964 0

Example 6-1. Findusers script, requires a username argument

#! /bin/sh

# finduser --- see if user named by first argument is logged in

if [ $# != 1 ]

then

echo Usage: finduser username >&2

exit 1

fi

who | grep $1

* * *

[1] C and C++ programmers take note! This is backward from what you're used to, and takes a while to get comfortable with.

[2] Mike Haertel points out that this has never been completely reliable: a_file could be changed in the interval between running test and running cat.

The case Statement

If you need to check a variable for one of many values, you could use a cascading series of if and elif tests, together with test:

if [ "X$1" = "X-f" ]

then

... Code for -f option

elif [ "X$1" = "X-d" ] || [ "X$1" = "X--directory" ] # long option allowed

then

... Code for -d option

else

echo $1: unknown option >&2

exit 1

fi

However, this is awkward to write and difficult to read. (The >&2 in the echo command sends the output to standard error. This is described in Section 7.3.2.) Instead, the shell's case construct should be used for pattern matching:

case $1 in

-f)

... Code for -f option

;;

-d | --directory) # long option allowed

... Code for -d option

;;

*)

echo $1: unknown option >&2

exit 1

# ;; is good form before `esac', but not required

esac

As can be seen, the value to be tested appears between case and in. Double-quoting the value, while not necessary, doesn't hurt either. The value is tested against each list of shell patterns in turn. When one matches, the corresponding body of code, up to the ;;, is executed. Multiple patterns may be used, separated by the | character, which in this context means "or." The patterns may contain any shell wildcard characters, and variable, command, and arithmetic substitutions are performed on the value before it is used for pattern matching.

The unbalanced right parenthesis after each pattern list is perhaps surprising; this is the only instance in the shell language of unbalanced delimiters. (In Section 14.3.7, we will see that bash and ksh actually allow a leading ( in front of the pattern list.)

It is typical, but not required, to use a final pattern of *, which acts as a default case. This is usually where you would print a diagnostic message and exit. As shown previously, the final case does not require the trailing ;;, although it's definitely good form to include it.

Looping

Besides the if and case statements, the shell's looping constructs are the workhorse facilities for getting things done.

for Loops

The for loop iterates over a list of objects, executing the loop body for each individual object in turn. The objects may be command-line arguments, filenames, or anything else that can be created in list format. In Section 3.2.7.1, we showed this two-line script to update an XML brochure file:

mv atlga.xml atlga.xml.old

sed 's/Atlanta/&, the capital of the South/' < atlga.xml.old > atlga.xml

Now suppose, as is much more likely, that we have a number of XML files that make up our brochure. In this case, we want to make the change in all the XML files. The for loop is perfect for this:

for i in atlbrochure*.xml

do

echo $i

mv $i $i.old

sed 's/Atlanta/&, the capital of the South/' < $i.old > $i

done

This loop moves each original file to a backup copy by appending a .old suffix, and then processing the file with sed to create the new file. It also prints the filename as a sort of running progress indicator, which is helpful when there are many files to process.

The in list part of the for loop is optional. When omitted, the shell loops over the command-line arguments. Specifically, it's as if you had typed for i in "$@":

for i # loop over command-line args

do

case $i in

-f) ...

;;

...

esac

done

while and until Loops

The shell's while and until loops are similar to loops in conventional programming languages. The syntax is:

while condition until condition

do do

statements

statements

done done

As for the if statement, condition may be a simple list of

Return Main Page Previous Page Next Page

®Online Book Reader