Linux 版 (精华区)

发信人: netiscpu (说不如做), 信区: Linux
标  题: Linux Shell Programming (Chapter 13)
发信站: 紫 丁 香 (Thu Jul 23 09:01:02 1998), 转信


               o Creating and Running Shell Programs
               o Using Variables
                    # Assigning a Value to a Variable
                    # Accessing the Value of a Variable
                    # Positional Parameters and Other Built-In Shell
                      Variables
               o The Importance of Quotation Marks
               o The test Command
                    # The tcsh Equivalent of the test Command
               o Conditional Statements
                    # The if Statement
                    # The case Statement
               o Iteration Statements
                    # The for Statement
                    # The while Statement
                    # The until Statement
                    # The shift Command
                    # The select Statement
                    # The repeat Statement
               o Functions
               o Summary
       
     _________________________________________________________________
                                      
   13
   
   
   Shell Programming
   
   
   The previous three chapters described how to use the most common Linux
   shell programs. I mentioned that these shell programs have powerful
   interpretive programming languages built into them. Now it's time to
   look at them in more detail.
   
   This chapter describes the fundamentals of shell programming and
   compares the bash, pdksh, and tcsh programming languages. This chapter
   covers the following topics:
     * Creating and running shell programs
       
     * Using shell variables
       
     * The importance of quotes
       
     * The test command
       
     * Conditional statements
       
     * Iteration statements
       
   This chapter contains several small examples of shell programs. Each
   new concept or command that is introduced has some example code that
   further helps to explain what is being presented.
   
   Creating and Running Shell Programs
   
   
   At the simplest level, shell programs are just files that contain one
   or more shell or Linux commands. These programs can be used to
   simplify repetitive tasks, to replace two or more commands that are
   always executed together with a single command, to automate the
   installation of other programs, and to write simple interactive
   applications.
   
   To create a shell program, you must create a file using a text editor
   and put the shell or Linux commands you want to be executed into that
   file. For example, assume you have a CD-ROM drive mounted on your
   Linux system. This CD-ROM device is mounted when the system is first
   started. If you later change the CD in the drive, you must force Linux
   to read the new directory contents. One way of achieving this is to
   put the new CD into the drive, unmount the CD-ROM drive using the
   Linux umount command, and then remount the drive using the Linux mount
   command. This sequence of steps is shown by the following commands:

umount /dev/cdrom
mount -t iso9660 /dev/cdrom /cdrom

   Instead of typing both of these commands each time you change the CD
   in your drive, you could create a shell program that would execute
   both of these commands for you. To do this, put the two commands into
   a file and call the file remount (or any other name you want).
   
   Several ways of executing the commands are contained in the remount
   file. One way to accomplish this is to make the file executable. This
   is done by entering the following command:
   
chmod +x remount

   This command changes the permissions of the file so that it is now
   executable. You can now run your new shell program by typing remount
   on the command line.
   
       ______________________________________________________________
                                      
     
     NOTE: The remount shell program must be in a directory that is in
     your search path, or the shell will not be able to find the program
     to execute. Also, if you are using tcsh to write programs, the
     first line of the shell program must start with a # for tcsh to
     recognize it as a tcsh program file.
     
     
       ______________________________________________________________
                                      
   Another way you can execute the shell program is to run the shell that
   the program was written for and pass the program in as a parameter to
   the shell. In a tcsh program, this is done by entering the following
   command:
   
tcsh remount

   This command starts up a new shell and tells it to execute the
   commands that are found in the remount file.
   
   A third way of executing the commands in a shell program file is to
   use the . command (in pdksh and bash) and the source command in tcsh.
   This command tells the shell to execute all the commands in the file
   that is passed as an argument to the command. For example, the
   following command can be used to tell bash or pdksh to execute the
   commands in the remount file:
   
. remount

   To do the same thing in tcsh, you would type the following command:
   
source remount

   Another situation in which a simple shell program can save a lot of
   time is described in the following example. Assume you were working on
   three different files in a directory, and at the end of every day you
   wanted to back up those three files onto a floppy disk. To do this you
   would type a series of commands similar to the following:

mr dir /a
mount -t msdos /dev/fd0 /a
cp file1 /a
cp file2 /a
cp file3 /a
umount /a

   As stated in the example, one way of doing this would be to mount the
   floppy drive and then type three copy commands, one for each file you
   wanted to copy. A simpler way would be to put the six commands into a
   text file called backup and then execute the backup command when you
   wanted to copy the three files onto the floppy drive.
   
       ______________________________________________________________
                                      
     
     NOTE: You will still have to ensure that the backup shell program
     is executable and is in a directory that is in your path before you
     run the command.
     
     
       ______________________________________________________________
                                      
   
   Using Variables
   
   
   As is the case with almost any language, the use of variables is very
   important in shell programs. You saw some of the ways in which shell
   variables can be used in the introductory shell chapters. Two of the
   variables that were introduced were the PATH variable and the PS1
   variable. These are examples of built-in shell variables, or variables
   that are defined by the shell program you are using. This section
   describes how you can create your own variables and use them in simple
   shell programs.
   
   Assigning a Value to a Variable
   
   
   In all three of the shells I have discussed, you can assign a value to
   a variable simply by typing the variable name followed by an equal
   sign and the value you want to assign to the variable. For example, if
   you wanted to assign a value of 5 to the variable count, you would
   enter the following command in bash or pdksh:
   
count=5

   With tcsh you would have to enter the following command to achieve the
   same results:
   
set count = 5

       ______________________________________________________________
                                      
     
     NOTE: With the bash and pdksh syntax for setting a variable, you
     must make sure that there are no spaces on either side of the equal
     sign. With tcsh, it doesn't matter if there are spaces or not.
     
     
       ______________________________________________________________
                                      
   Notice that you do not have to declare the variable as you would if
   you were programming in C or Pascal. This is because the shell
   language is a non-typed interpretive language. This means that you can
   use the same variable to store character strings that you use to store
   integers. You would store a character string into a variable in the
   same way that you stored the integer into a variable. For example:
        name=Garry - (for pdksh and bash)
       
        set name = Garry - (for tcsh)
       
   
   Accessing the Value of a Variable
   
   
   Once you have stored a value into a variable, how do you get the value
   back out? You do this in the shell by preceding the variable name with
   a dollar sign ($). If you wanted to print the value stored in the
   count variable to the screen, you would do so by entering the
   following command:
   
echo $count

       ______________________________________________________________
                                      
     
     NOTE: If you omitted the $ from the preceding command, the echo
     command would display the word count on-screen.
     
     
       ______________________________________________________________
                                      
   
   Positional Parameters and Other Built-In Shell Variables
   
   
   The shell has knowledge of a special kind of variable called a
   positional parameter. Positional parameters are used to refer to the
   parameters that were passed to a shell program on the command line or
   a shell function by the shell script that invoked the function. When
   you run a shell program that requires or supports a number of
   command-line options, each of these options is stored into a
   positional parameter. The first parameter is stored into a variable
   named 1, the second parameter is stored into a variable named 2, and
   so forth. These variable names are reserved by the shell so that you
   can't use them as variables you define. To access the values stored in
   these variables, you must precede the variable name with a dollar sign
   ($) just as you do with variables you define.
   
   The following shell program expects to be invoked with two parameters.
   The program takes the two parameters and prints the second parameter
   that was typed on the command line first and the first parameter that
   was typed on the command line second.

#program reverse, prints the command line parameters out in reverse #order
echo "$2" "$1"

   If you invoked this program by entering
   
reverse hello there

   the program would return the following output:
   
there hello

   Several other built-in shell variables are important to know about
   when you are doing a lot of shell programming. Table 13.1 lists these
   variables and gives a brief description of what each is used for.
   
   Table 13.1. Built-in shell variables.
   
                                      
                                Variable Use
   $# Stores the number of command-line arguments that were passed to the
                               shell program.
      $? Stores the exit value of the last command that was executed.
   $0 Stores the first word of the entered command (the name of the shell
                                 program).
   $* Stores all the arguments that were entered on the command line ($1
                                  $2 ...).
    "$@" Stores all the arguments that were entered on the command line,
                    individually quoted ("$1" "$2" ...).
                                      
   The Importance of Quotation Marks
   
                                      
   The use of the different types of quotation marks is very important in
   shell programming. Both kinds of quotation marks and the backslash
   character are used by the shell to perform different functions. The
   double quotation marks (""), the single quotation marks (''), and the
   backslash (\) are all used to hide special characters from the shell.
   Each of these methods hides varying degrees of special characters from
   the shell.
   
   The double quotation marks are the least powerful of the three
   methods. When you surround characters with double quotes, all the
   whitespace characters are hidden from the shell, but all other special
   characters are still interpreted by the shell. This type of quoting is
   most useful when you are assigning strings that contain more than one
   word to a variable. For example, if you wanted to assign the string
   hello there to the variable greeting, you would type the following
   command:

greeting="hello there" (for bash and pdksh)
set greeting = "hello there" (for tcsh)

   This command would store the hello there string into the greeting
   variable as one word. If you typed this command without using the
   quotes, you would not get the results you wanted. bash and pdksh would
   not understand the command and would return an error message. tcsh
   would assign the value hello to the greeting variable and ignore the
   rest of the command line.
   
   Single quotes are the most powerful form of quoting. They hide all
   special characters from the shell. This is useful if the command that
   you enter is intended for a program other than the shell.
   
   Because the single quotes are the most powerful, you could have
   written the hello there variable assignment using single quotes. You
   might not always want to do this. If the string being assigned to the
   greeting variable contained another variable, you would have to use
   the double quotes. For example, if you wanted to include the name of
   the user in your greeting, you would type the following command:

greeting="hello there $LOGNAME" (for bash and pdksh)
set greeting="hello there $LOGNAME" (for tcsh)

       ______________________________________________________________
                                      
     
     NOTE: Remember that the LOGNAME variable is a shell variable that
     contains the Linux username of the person who is logged in to the
     system.
     
     
       ______________________________________________________________
                                      
   This would store the value hello there root into the greeting variable
   if you were logged in to Linux as root. If you tried to write this
   command using single quotes it wouldn't work, because the single
   quotes would hide the dollar sign from the shell and the shell
   wouldn't know that it was supposed to perform a variable substitution.
   The greeting variable would be assigned the value hello there $LOGNAME
   if you wrote the command using single quotes.
   
   Using the backslash is the third way of hiding special characters from
   the shell. Like the single quotation mark method, the backslash hides
   all special characters from the shell, but it can hide only one
   character at a time, as opposed to groups of characters. You could
   rewrite the greeting example using the backslash instead of double
   quotation marks by using the following command:

greeting=hello\ there (for bash and pdksh)
set greeting=hello\ there (for tcsh)

   In this command, the backslash hides the space character from the
   shell, and the string hello there is assigned to the greeting
   variable.
   
   Backslash quoting is used most often when you want to hide only a
   single character from the shell. This is usually done when you want to
   include a special character in a string. For example, if you wanted to
   store the price of a box of computer disks into a variable named
   disk_price, you would use the following command:

disk_price=\$5.00 (for bash and pdksh)
set disk_price = \$5.00 (for tcsh)

   The backslash in this example would hide the dollar sign from the
   shell. If the backslash were not there, the shell would try to find a
   variable named 5 and perform a variable substitution on that variable.
   Assuming that no variable named 5 were defined, the shell would assign
   a value of .00 to the disk_price variable. This is because the shell
   would substitute a value of null for the $5 variable.
   
       ______________________________________________________________
                                      
     
     NOTE: The disk_price example could also have used single quotes to
     hide the dollar sign from the shell.
     
     
       ______________________________________________________________
                                      
   The back quote marks (") perform a different function. They are used
   when you want to use the results of a command in another command. For
   example, if you wanted to set the value of the variable contents equal
   to the list of files in the current directory, you would type the
   following command:

contents='ls' (for bash and pdksh)
set contents = 'ls' (for tcsh)

   This command would execute the ls command and store the results of the
   command into the contents variable. As you will see in the section
   "Iteration Statements," this feature can be very useful when you want
   to write a shell program that performs some action on the results of
   another command.
   
   The test Command
   
   
   In bash and pdksh, a command called test is used to evaluate
   conditional expressions. You would typically use the test command to
   evaluate a condition that is used in a conditional statement or to
   evaluate the entrance or exit criteria for an iteration statement. The
   test command has the following syntax:
   
test expression

   or
   
 [ expression ]

   Several built-in operators can be used with the test command. These
   operators can be classified into four groups: integer operators,
   string operators, file operators, and logical operators.
   
   The shell integer operators perform similar functions to the string
   operators except that they act on integer arguments. Table 13.2 lists
   the test command's integer operators.
   
   Table 13.2. The test command's integer operators.
   
                                      
                              Operator Meaning
            int1 -eq int2 Returns True if int1 is equal to int2.
    int1 -ge int2 Returns True if int1 is greater than or equal to int2.
          int1 -gt int2 Returns True if int1 is greater than int2.
     int1 -le int2 Returns True if int1 is less than or equal to int2.
           int1 -lt int2 Returns True if int1 is less than int2.
          int1 -ne int2 Returns True if int1 is not equal to int2.
                                      
   The string operators are used to evaluate string expressions. Table
   13.3 lists the string operators that are supported by the three shell
   programming languages.
   
   Table 13.3. The test command's string operators.
   
                                      
                              Operator Meaning
           str1 = str2 Returns True if str1 is identical to str2.
        str1 != str2 Returns True if str1 is not identical to str2.
                    str Returns True if str is not null.
       -n str Returns True if the length of str is greater than zero.
         -z str Returns True if the length of str is equal to zero.
                                      
   The test command's file operators are used to perform functions such
   as checking to see if a file exists and checking to see what kind of
   file is passed as an argument to the test command. Table 13.4 lists
   the test command's file operators.
   
   Table 13.4. The test command's file operators.
   
                                      
                              Operator Meaning
         -d filename Returns True if file, filename is a directory.
      -f filename Returns True if file, filename is an ordinary file.
   -r filename Returns True if file, filename can be read by the process.
      -s filename Returns True if file, filename has a nonzero length.
      -w filename Returns True if file, filename can be written by the
                                  process.
         -x filename Returns True if file, filename is executable.
                                      
   The test command's logical operators are used to combine two or more
   of the integer, string, or file operators or to negate a single
   integer, string, or file operator. Table 13.5 lists the test command's
   logical operators.
   
   Table 13.5. The test command's logical operators.
   
                                      
                              Command Meaning
                  ! expr Returns True if expr is not true.
          expr1 -a expr2 Returns True if expr1 and expr2 are true.
           expr1 -o expr2 Returns True if expr1 or expr2 is true.
                                      
   The tcsh Equivalent of the test Command
   
                                      
   The tcsh does not have a test command, but it supports the same
   function using expressions. The expression operators that tcsh
   supports are almost identical to those supported by the C language.
   These expressions are used mostly in the if and while commands, which
   are covered later in this chapter in the "Conditional Statements" and
   "Iteration Statements" sections.
   
   The tcsh expressions support the same kind of operators as the bash
   and pdksh test command. These are integer, string, file, and logical
   expressions. The integer operators supported by tcsh expressions are
   listed in Table 13.6.
   
   Table 13.6. The tcsh expression integer operators.
   
                                      
                              Operator Meaning
      int1 <= int2 Returns True if int1 is less than or equal to int2.
    int1 >= int2 Returns True if int1 is greater than or equal to int2.
            int1 < int2 Returns True if int1 is less than int2.
           int1 > int2 Returns True if int1 is greater than int2.
                                      
   The string operators that tcsh expressions support are listed in Table
   13.7.
   
   Table 13.7. The tcsh expression string operators.
   
                                      
                              Operator Meaning
            str1 == str2 Returns True if str1 is equal to str2.
          str1 != str2 Returns True if str1 is not equal to str2.
                                      
   The file operators that tcsh expressions support are listed in Table
   13.8.
   
   Table 13.8. The tcsh expression file operators.
   
                                      
                              Operator Meaning
                 -r file Returns True if file is readable.
                 -w file Returns True if file is writable.
                -x file Returns True if file is executable.
                    -e file Returns True if file exists.
         -o file Returns True if file is owned by the current user.
                 -z file Returns True if file is of size 0.
              -f file Returns True if file is a regular file.
             -d file Returns True if file is a directory file.
                                      
   The logical operators that tcsh expressions support are listed in
   Table 13.9.
   
   Table 13.9. The tcsh expression logical operators.
   
                                      
                              Operator Meaning
       exp1 || exp2 Returns True if exp1 is true or if exp2 is true.
        exp1 && exp2 Returns True if exp1 is true and exp2 is true.
                   ! exp Returns True if exp is not true.
                                      
   Conditional Statements
   
                                      
   The bash, pdksh, and tcsh each have two forms of conditional
   statements. These are the if statement and the case statement. These
   statements are used to execute different parts of your shell program
   depending on whether certain conditions are true. As with most
   statements, the syntax for these statements is slightly different
   between the different shells.
   
   The if Statement
   
   
   All three shells support nested if...then...else statements. These
   statements provide you with a way of performing complicated
   conditional tests in your shell programs. The syntax of the if
   statement is the same for bash and pdksh and is shown here:

if [ expression ]
then
commands
elif [ expression2 ]
then
commands
else
commands
fi

       ______________________________________________________________
                                      
     
     NOTE: The elif and else clauses are both optional parts of the if
     statement. Also note that bash and pdksh use the reverse of the
     statement name in most of their complex statements to signal the
     end of the statement. In this statement the fi keyword is used to
     signal the end of the if statement.
     
     
       ______________________________________________________________
                                      
   The elif statement is an abbreviation of else if. This statement is
   executed only if none of the expressions associated with the if
   statement or any elif statements before it were true. The commands
   associated with the else statement are executed only if none of the
   expressions associated with the if statement or any of the elif
   statements were true.
   
   In tcsh, the if statement has two different forms. The first form
   provides the same function as the bash and pdksh if statement. This
   form of if statement has the following syntax:

if (expression1) then
commands
else if (expression2) then
commands
else
commands
endif

       ______________________________________________________________
                                      
     
     NOTE: Once again, the else if and else parts of the if statement
     are optional.
     
     
       ______________________________________________________________
                                      
   The second form of if statement provided by tcsh is a simple version
   of the first if statement. This form of if statement evaluates only a
   single expression. If the expression is true, it executes a single
   command; if the expression is false, nothing happens. The syntax for
   this form of if statement is the following:
   
if (expression) command

   This statement could be written using the first form of if statement
   by writing the if without any else or else if clauses. This form just
   saves a little typing.
   
   The following is an example of a bash or pdksh if statement. This
   statement checks to see if there is a .profile file in the current
   directory:

if [ -f .profile ]
then
echo "There is a .profile file in the current directory."
else
echo "Could not find the .profile file."
fi

   The same statement written using the tcsh syntax is shown here:

#
if ( { -f .profile } ) then
echo "There is a .profile file in the current directory."
else
echo "Could not find the .profile file."
endif

       ______________________________________________________________
                                      
     
     NOTE: Notice that in the tcsh example the first line starts with a
     #. This is required for tcsh to recognize the file containing the
     commands as a tcsh script file.
     
     
       ______________________________________________________________
                                      
   
   The case Statement
   
   
   The case statement enables you to compare a pattern with several other
   patterns and execute a block of code if a match is found. The shell
   case statement is quite a bit more powerful than the case statement in
   Pascal or the switch statement in C. This is because in the shell case
   statement you can compare strings with wildcard characters in them,
   whereas with the Pascal and C equivalents you can compare only
   enumerated types or integer values.
   
   Once again, the syntax for the case statement is identical for bash
   and pdksh and different for tcsh. The syntax for bash and pdksh is the
   following:

case string1 in
str1)
commands;;
str2)
commands;;
*)
commands;;
esac

   string1 is compared to str1 and str2. If one of these strings matches
   string1, the commands up until the double semicolon (;;) are executed.
   If neither str1 nor str2 matches string1, the commands associated with
   the asterisk are executed. This is the default case condition because
   the asterisk matches all strings.
   
   The tcsh equivalent of the bash and pdksh case statement is called the
   switch statement. This statement's syntax closely follows the C switch
   statement syntax. Here it is:

switch (string1)
case str1:
statements
breaksw
case str2:
statements
breaksw
default:
statements
breaksw
endsw

   This behaves in the same manner as the bash and pdksh case statement.
   Each string following the keyword case is compared with string1. If
   any of these strings matches string1, the code following it up until
   the breaksw keyword is executed. If none of the strings matches, the
   code following the default keyword up until the breaksw keyword is
   executed.
   
   The following code is an example of a bash or pdksh case statement.
   This code checks to see if the first command-line option was -i or -e.
   If it was -i, the program counts the number of lines in the file
   specified by the second command-line option that begins with the
   letter i. If the first option was -e, the program counts the number of
   lines in the file specified by the second command-line option that
   begins with the letter e. If the first command-line option was not -i
   or -e, the program prints a brief error message to the screen.

case $1 in
-i)
count='grep ^i $2 | wc -l'
echo "The number of lines in $2 that start with an i is $count"
;;
-e)
count='grep ^e $2 | wc -l'
echo "The number of lines in $2 that start with an e is $count"
;;
* )
echo "That option is not recognized"
;;
esac

   The same example written in tcsh syntax is shown here:

# remember that the first line must start with a # when using tcsh
switch ( $1 )
case -i | i:
set count = 'grep ^i $2 | wc -l'
echo "The number of lines in $2 that begin with i is $count"
breaksw
case -e | e:
set count = 'grep ^e $2 | wc -l'
echo "The number of lines in $2 that begin with e is $count"
breaksw
default:
echo "That option is not recognized"
breaksw
endsw

   
   Iteration Statements
   
   
   The shell languages also provide several iteration or looping
   statements. The most commonly used of these is the for statement.
   
   The for Statement
   
   
   The for statement executes the commands that are contained within it a
   specified number of times. bash and pdksh have two variations of the
   for statement.
   
       ______________________________________________________________
                                      
     
     NOTE: The for statement syntax is the same in both bash and pdksh.
     
     
       ______________________________________________________________
                                      
   The first form of the for statement that bash and pdksh support has
   the following syntax:

for var1 in list
do
commands
done

   In this form, the for statement executes once for each item in the
   list. This list can be a variable that contains several words
   separated by spaces, or it can be a list of values that is typed
   directly into the statement. Each time through the loop, the variable
   var1 is assigned the current item in the list, until the last one is
   reached.
   
   The second form of for statement has the following syntax:

for var1
do
statements
done

   In this form, the for statement executes once for each item in the
   variable var1. When this syntax of the for statement is used, the
   shell program assumes that the var1 variable contains all the
   positional parameters that were passed in to the shell program on the
   command line.
   
   Typically this form of for statement is the equivalent of writing the
   following for statement:

for var1 in "$@"
do
statements
done

   The equivalent of the for statement in tcsh is called the foreach
   statement. It behaves in the same manner as the bash and pdksh for
   statement. The syntax of the foreach statement is the following:

foreach name (list)
commands
end

   The following is an example of the bash or pdksh style of for
   statement. This example takes as command-line options any number of
   text files. The program reads in each of these files, converts all the
   letters to uppercase, and then stores the results in a file of the
   same name but with a .caps extension.

for file
do
tr a-z A-Z < $file >$file.caps
done

   The same example written in tcsh shell language is shown next:

#
foreach file ($*)
tr a-z A-Z < $file >$file.caps
end

   
   The while Statement
   
   
   Another iteration statement offered by the shell programming language
   is the while statement. This statement causes a block of code to be
   executed while a provided conditional expression is true. The syntax
   for the while statement in bash and pdksh is the following:

while expression
do
statements
done

   The syntax for the while statement in tcsh is the following:

while (expression)
statements
end

   The following is an example of the bash and pdksh style of while
   statement. This program lists the parameters that were passed to the
   program, along with the parameter number.

count=1
while [ -n "$*" ]
do
echo "This is parameter number $count $1"
shift
count='expr $count + 1'
done

   As you will see in the section titled "The shift Command," the shift
   command moves the command-line parameters over one to the left.
   
   The same program written in the tcsh language is shown next:

#
set count = 1
while ( "$*" != "" )
echo "This is parameter number $count $1"
shift
set count = 'expr $count + 1'
end

   
   The until Statement
   
   
   The until statement is very similar in syntax and function to the
   while statement. The only real difference between the two is that the
   until statement executes its code block while its conditional
   expression is false, and the while statement executes its code block
   while its conditional expression is true. The syntax for the until
   statement in bash and pdksh is

until expression
do
commands
done

   The same example that was used for the while statement can be used for
   the until statement. All you have to do to make it work is negate the
   condition. This is shown in the following code:

count=1
until [ -z "$*" ]
do
echo "This is parameter number $count $1"
shift
count='expr $count + 1'
done

   The only difference between this example and the while statement
   example is that the -n test command option (which means that the
   string has nonzero length) was removed, and the -z test option (which
   means that the string has zero length) was put in its place.
   
   In practice the until statement is not very useful, because any until
   statement you write can also be written as a while statement.
   
       ______________________________________________________________
                                      
     
     NOTE: tcsh does not have an equivalent of the until statement other
     than rewriting it as a while loop.
     
     
       ______________________________________________________________
                                      
   
   The shift Command
   
   
   bash, pdksh, and tcsh all support a command called shift. The shift
   command moves the current values stored in the positional parameters
   to the left one position. For example, if the values of the current
   positional parameters are
   
$1 = -r $2 = file1 $3 = file2

   and you executed the shift command
   
shift

   the resulting positional parameters would be as follows:
   
$1 = file1 $2 = file2

   You can also move the positional parameters over more than one place
   by specifying a number with the shift command. The following command
   would shift the positional parameters two places:
   
shift 2

   This is a very useful command when you have a shell program that needs
   to parse command-line options. This is true because options are
   typically preceded by a hyphen and a letter that indicates what the
   option is to be used for. Because options are usually processed in a
   loop of some kind, you often want to skip to the next positional
   parameter once you have identified which option should be coming next.
   For example, the following shell program expects two command-line
   options&#151;one that specifies an input file and one that specifies
   an output file. The program reads the input file, translates all the
   characters in the input file into uppercase, then stores the results
   in the specified output file.
   
       ______________________________________________________________
                                      
     
     NOTE: The following example was written using bash, pdksh syntax.
     
     
       ______________________________________________________________
                                      
while [ "$1" ]
do
if [ "$1" = "-i" ] then
infile="$2"
shift 2
elif [ "$1" = "-o" ]
then
outfile="$2"
shift 2
else
echo "Program $0 does not recognize option $1"
fi
done
tr a-z A-Z <$infile >$outfile

   
   The select Statement
   
   
   pdksh offers one iteration statement that neither bash nor tcsh
   provides. This is the select statement. This is actually a very useful
   statement. It is quite a bit different from the other iteration
   statements because it actually does not execute a block of shell code
   repeatedly while a condition is true or false. What the select
   statement does is enable you to automatically generate simple text
   menus. The syntax for the select statement is

select menuitem [in list_of_items]
do
commands
done

   where square brackets are used to enclose the optional part of the
   statement.
   
   When a select statement is executed, pdksh creates a numbered menu
   item for each element in the list_of_items. This list_of_items can be
   a variable that contains more than one item, such as choice1 choice2,
   or it can be a list of choices typed in the command. For example:
   
select menuitem in choice1 choice2 choice3

   If the list_of_items is not provided, the select statement uses the
   positional parameters just as with the for statement.
   
   Once the user of the program containing a select statement picks one
   of the menu items by typing the number associated with it, the select
   statement stores the value of the selected item in the menuitem
   variable. The statements contained in the do block can then perform
   actions on this menu item.
   
   The following example illustrates a potential use for the select
   statement. This example displays three menu items, and when the user
   chooses one of them it asks whether that was the intended selection.
   If the user enters anything other than y or Y, the menu is
   redisplayed.

select menuitem in pick1 pick2 pick3
do
echo "Are you sure you want to pick $menuitem"
read res
if [ $res = "y" -o $res = "Y" ]
then
break
fi
done

   A few new commands are introduced in this example. The read command is
   used to get input from the user. It stores anything that the user
   types into the specified variable. The break command is used to exit a
   while, until, repeat, select, or for statement.
   
   The repeat Statement
   
   
   tcsh has an iteration statement that has no equivalent in pdksh or
   bash. This is the repeat statement. The repeat statement executes a
   single command a specified number of times. The syntax for the repeat
   statement is the following:
   
repeat count command

   The following is an example of the repeat statement. It takes a set of
   numbers as command-line options and prints that number of periods to
   the screen. This program acts as a very primitive graphing program.

#
foreach num ($*)
repeat $num echo -n "."
echo ""
end

       ______________________________________________________________
                                      
     
     NOTE: Any repeat statement can be rewritten as a while or for
     statement. The repeat syntax is simply more convenient.
     
     
       ______________________________________________________________
                                      
   
   Functions
   
   
   The shell languages enable you to define your own functions. These
   functions behave in much the same way as functions you define in C or
   other programming languages. The main advantage of using functions as
   opposed to writing all of your shell code in line is for
   organizational purposes. Code written using functions tends to be much
   easier to read and maintain and also tends to be smaller, because you
   can group common code into functions instead of putting it everywhere
   it is needed.
   
   The syntax for creating a function in bash and pdksh is the following:
   
fname () {
shell commands
}

   pdksh also allows the following syntax:

function fname {
shell commands
}

   Both of these forms behave in the exact same way.
   
   Once you have defined your function using one of these forms, you can
   invoke it by entering the following command:
   
fname [parm1 parm2 parm3 ...]

       ______________________________________________________________
                                      
     
     NOTE: The tcsh shell does not support functions.
     
     
       ______________________________________________________________
                                      
   Notice that you can pass any number of parameters to your function.
   When you do pass parameters to a function, it sees those parameters as
   positional parameters, just as a shell program does when you pass it
   parameters on the command line. For example, the following shell
   program contains several functions, each of which is performing a task
   associated with one of the command-line options. This example
   illustrates many of the topics covered in this chapter. It reads all
   the files that are passed on the command line and&#151;depending on
   the option that was used&#151;writes the files out in all uppercase
   letters, writes the files out in all lowercase letters, or prints the
   files.

upper () {
shift
for i
do
tr a-z A-Z <$1 >$1.out
rm $1
mv $1.out $1
shift
done; }
lower () {
shift
for i
do
tr A-Z a-z <$1 >$1.out
rm $1
mv $1.out $1
shift
done; }
print () {
shift
for i
do
lpr $1
shift
done; }
usage_error () {
echo "$1 syntax is $1 <option> <input files>"
echo ""
echo "where option is one of the following"
echo "p &#151; to print frame files"
echo "u &#151; to save as uppercase"
echo "l &#151; to save as lowercase"; }
case $1
in
p | -p) print $@;;
u | -u) upper $@;;
l | -l) lower $@;;
*) usage_error $0;;
esac

   
   Summary
   
   
   This chapter introduced you to many of the features of the bash,
   pdksh, and tcsh programming languages. As you become familiar with
   using Linux, you will find that you use shell programming languages
   more and more often.
   
   Even though the shell languages are very powerful and also quite easy
   to learn, you might run into some situations where shell programs are
   not suited to the problem you are solving. In these cases you may want
   to investigate the possibility of using one of the other languages
   available under Linux. Some of your options are C and C++, which are
   described in Chapters 27, "Programming in C" and 28, "Programming in
   C++;" gawk, which is described in Chapter 26, "gawk;" and Perl, which
   is described in Chapter 29, "Perl."


--

                              Enjoy Linux!
                          -----It's FREE!-----

※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:684.402毫秒