14.7. Functions

 <  Day Day Up  >  

Functions were introduced to the Bourne shell in AT&T's UNIX SystemVR2 and have been enhanced in the Bourne Again shell. A function is a name for a command or group of commands. Functions are used to modularize your program and make it more efficient. They are executed in context of the current shell. In other words, a child process is not spawned as it is when running an executable program such as ls . You may even store functions in another file and load them into your script when you are ready to use them.

Here is a review of some of the important rules about using functions.

  1. The shell determines whether you are using an alias, a function, a built-in command, or an executable program (or script) found on the disk. It looks for aliases first, then functions, built-in commands, and executables last.

  2. A function must be defined before it is used.

  3. The function runs in the current environment; it shares variables with the script that invoked it, and lets you pass arguments by assigning them as positional parameters. Local variables can be created within a function by using the local function.

  4. If you use the exit command in a function, you exit the entire script. If you exit the function, you return to where the script left off when the function was invoked.

  5. The return statement in a function returns the exit status of the last command executed within the function or the value of the argument given.

  6. Functions can be exported to subshells with the export “f built-in command.

  7. To list functions and definitions, use the declare “f command. To list just function names , use declare “F . [5]

    [5] Only on bash versions 2.x.

  8. Traps, like variables, are global within functions. They are shared by both the script and the functions invoked in the script. If a trap is defined in a function, it is also shared by the script. This could have unwanted side effects.

  9. If functions are stored in another file, they can be loaded into the current script with the source or dot command.

  10. Functions can be recursive; that is, they can call themselves . There is no limit imposed for the number of recursive calls.

FORMAT

 function function_name { commands ; commands; } 

Example 14.55.
  function dir { echo "Directories: ";ls -lawk '/^d/ {print $NF}'; }  

EXPLANATION

The keyword function is followed by the name of the function dir . (Sometimes empty parentheses follow the function name, but they are not necessary.) The commands within the curly braces will be executed when dir is typed. The purpose of the function is to list only the subdirectories below the present working directory. The spaces surrounding the first curly brace are required.

14.7.1 Unsetting Functions

To remove a function from memory, use the unset command.

FORMAT

 unset -f function_name 

14.7.2 Exporting Functions

Functions may be exported so that subshells know about them.

FORMAT

 export -f function_name 

14.7.3 Function Arguments and the Return Value

Because the function is executed within the current shell, the variables will be known to both the function and the shell. Any changes made to your environment in the function will also be made to the shell.

Arguments

Arguments can be passed to functions by using positional parameters. The positional parameters are private to the function; that is, arguments to the function will not affect any positional parameters used outside the function. See Example 14.56.

The Built-In local Function

To create local variables that are private to the function and will disappear after the function exits, use the built-in local function. See Example 14.57.

The Built-In return Function

The return command can be used to exit the function and return control to the program at the place where the function was invoked. (Remember, if you use exit anywhere in your script, including within a function, the script terminates.) The return value of a function is really just the value of the exit status of the last command in the script, unless you give a specific argument to the return command. If a value is assigned to the return command, that value is stored in the ? variable and can hold an integer value between 0 and 256. Because the return command is limited to returning only an integer between 0 and 256, you can use command substitution to capture the output of a function. Place the entire function in parentheses preceded by a $ (e.g., $(function_name) ), or traditional backquotes to capture and assign the output to a variable just as you would if getting the output of a UNIX command.

Example 14.56.
 (Passing Arguments) (The Script)     #!/bin/bash  # Scriptname: checker   # Purpose: Demonstrate function and arguments  1  function Usage { echo "error: $*" 2>&1; exit 1; }  2   if (($# != 2))     then 3        Usage " 
 (Passing Arguments) (The Script) #!/bin/bash  # Scriptname: checker   # Purpose: Demonstrate function and arguments  1  function Usage { echo "error: $*" 2>&1; exit 1; }  2 if (($# != 2)) then 3 Usage "$0: requires two arguments" fi 4 if [[ ! (-r $1 && -w $1) ]] then 5 Usage "$1: not readable and writable" fi 6 echo The arguments are: $* < Program continues here > (The Command Line and Output) $  checker   error: checker: requires two arguments  $  checker file1 file2   error: file1: not readable and writable  $  checker filex file2   The arguments are filex file2  
: requires two arguments" fi 4 if [[ ! (-r && -w) ]] then 5 Usage ": not readable and writable" fi 6 echo The arguments are: $* < Program continues here > (The Command Line and Output) $ checker error: checker: requires two arguments $ checker file1 file2 error: file1: not readable and writable $ checker filex file2 The arguments are filex file2

EXPLANATION

1 The function called Usage is defined. It will be used to send an error message to standard error (the screen). Its arguments consist of any string of characters sent when the function is called. The arguments are stored in $* , the special variable that contains all positional parameters. Within a function, positional parameters are local and have no effect on those positional parameters used outside the function.

2 If the number of arguments being passed into the script from the command line does not equal 2, the program branches to line 3.

3 When the Usage function is called, the string $0: requires two arguments is passed to the function and stored in the $* varable. The echo statement will then send the message to standard error and the script will exit with an exit status of 1 to indicate that something went wrong. [a]

[a] With the old test form, the expression is written if [ ! \(-r $1 -a -w $1 \) ] .

4, 5 If the first argument coming into the program from the command line is not the name of a readable and writable file, the Usage function will be called with $1: not readable and writable as its argument.

6 The arguments coming into the script from the command line are stored in $* . This has no effect on the $* in the function.

Example 14.57.
 (Using the return Command) (The Script)     #!/bin/bash  # Scriptname: do_increment  1   increment ()  { 2      local sum;     # sum is known only in this function 3      let "sum= + 1" 4      return $sum    # Return the value of sum to the script     } 5   echo  n "The sum is " 6   increment 5  # Call function increment; pass 5 as a   # parameter; 5 becomes  for the increment function  7   echo $?  # The return value is stored in $?  8   echo  $sum  # The variable "sum" is not known here  (The Output) 4,6  The sum is 6  8 

EXPLANATION

  1. The function called increment is defined.

  2. The built-in local function makes variable sum local (private) to this function. It will not exist outside the function. When the function exits, it will be removed.

  3. When the function is called, the value of the first argument, $1 , will be incremented by one and the result assigned to sum .

  4. The return built-in command, when given an argument, returns to the main script after the line where the function was invoked. It stores its argument in the ? variable.

  5. The string is echoed to the screen.

  6. The increment function is called with an argument of 5 .

  7. When the function returns, its exit status is stored in the ? variable. The exit status is the exit value of the last command executed in the function unless an explicit argument is used in the return statement. The argument for return must be an integer between 0 and 255.

  8. Although the sum was defined in the function increment , it is local in scope, and therefore also not known outside the function. Nothing is printed.

Example 14.58.
 (Using Command Substitution) (The Script)     #!/bin/bash  # Scriptname: do_square  1  function square  {       local sq  # sq is local to the function  let "sq= * "       echo "Number to be squared is ." 2      echo "The result is $sq "     } 3   echo "Give me a number to square. "     read number 4  value_returned=$(square $number)   # Command substitution  5   echo   "$value_returned" (The Command Line and Output)     $  do_square  3  Give me a number to square.   10  5  Number to be squared is 10.   The result is 100  

EXPLANATION

  1. The function called square is defined. Its purpose, when called, is to multiply its argument, $1 , times itself.

  2. The result of squaring the number is printed.

  3. The user is asked for input. This is the line where the program starts executing.

  4. The function square is called with a number (input from the user) as its argument. Command substitution is performed because the function is enclosed in parentheses preceded by a $ . The output of the function, both of its echo statements, is assigned to the variable value_returned .

  5. The value returned from the command substitution is printed.

14.7.4 Functions and the source (or dot ) Command

Storing Functions

Functions are often defined in the .profile file so that when you log in, they will be defined. Functions can be exported, and they can be stored in a file. Then when you need the function, the source or dot command is used with the name of the file to activate the definitions of the functions within it.

Example 14.59.
 1   $  cat myfunctions  2  function go() {  cd $HOME/bin/prog         PS1='`pwd` > '         ls  }  3  function greetings() {  echo "Hi ! Welcome to my world." ;  }  4   $  source myfunctions  5   $  greetings george   Hi george! Welcome to my world.  

EXPLANATION

  1. The file myfunctions is displayed. It contains two function definitions.

  2. The first function defined is called go . It sets the primary prompt to the present working directory.

  3. The second function defined is called greetings . It will greet the name of the user passed in as an argument.

  4. The source or dot command loads the contents of the file myfunctions into the shell's memory. Now both functions are defined for this shell.

  5. The greetings function is invoked and executed.

Example 14.60.
 (The dbfunctions file shown below contains functions to be used by the main program. See  cd for complete script.) 1   $  cat dbfunctions  2  function addon ()  {  # Function defined in file dbfunctions  3       while true         do             echo "Adding information "             echo "Type the full name of employee "             read name             echo "Type address for employee "             read address             echo "Type start date for employee (4/10/88) :"             read startdate             echo $name:$address:$startdate             echo n "Is this correct? "             read ans             case "$ans"  in             [Yy]*)                  echo "Adding info..."                  echo $name:$address:$startdate>>datafile                  sort u datafile o datafile                  echo n "Do you want to go back to the main menu? "                  read ans                  if [[ $ans == [Yy] ]]                  then 4  return   # Return to calling program  else 5                continue  # Go to the top of the loop  fi                  ;;             *)             echo "Do you want to try again? "             read answer             case "$answer" in             [Yy]*) continue;;             *) exit;;             esac                 ;;         esac     done 6   }  # End of function definition  ------------------------------------------------------------- (The Command Line) 7   $  more mainprog  #!/bin/bash  # Scriptname: mainprog   # This is the main script that will call the function, addon  datafile=$HOME/bourne/datafile 8  source dbfunctions   # The file is loaded into memory  if [ ! e $datafile ]     then         echo "$(basename $datafile) does not exist" >&2         exit 1     fi 9       echo "Select one: "         cat <<EOF             [1] Add info             [2] Delete info             [3] Update info             [4] Exit         EOF         read choice         case $choice in 10          1)  addon   # Calling the addon function  ;;             2)  delete   # Calling the delete function  ;;             3)   update                  ;;             4)                  echo Bye                  exit 0                  ;;             *)   echo Bad choice                  exit 2                  ;;         esac         echo Returned from function call         echo The name is $name  # Variable set in the function are known in this shell.  done 

EXPLANATION

  1. The dbfunctions file is displayed.

  2. The addon function is defined. Its function is to add new information to datafile .

  3. A while loop is entered. It will loop forever unless a loop control statement such as break or continue is included in the body of the loop.

  4. The return command sends control back to the calling program where the function was called.

  5. Control is returned to the top of the while loop.

  6. The closing curly brace ends the function definition.

  7. This is the main script. The function addon will be used in this script.

  8. The source command loads the file dbfunctions into the program's memory. Now the function addon is defined for this script and available for use. It is as though you had just defined the function right here in the script.

  9. A menu is displayed with the here document . The user is asked to select a menu item.

  10. The addon function is invoked.

 <  Day Day Up  >  


UNIX Shells by Example
UNIX Shells by Example (4th Edition)
ISBN: 013147572X
EAN: 2147483647
Year: 2004
Pages: 454
Authors: Ellie Quigley

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net