part in electronic, paper or other forms without written permission is prohibited. Working with Korn Shell SkillSoft Corporation. (c) 2003. Copying Prohibited. Reprinted for Raman Ramachandran, IBM ramanramachandran@in.ibm.com Reprinted with permission as a subscription benefit of Books24x7, http://www.books24x7.com/ Table of Contents Chapter 6: How Functions Work.....................................................................................................1 Using Functions in the Korn Shell..................................................................................................2 The Structure of a Function in the Korn Shell.........................................................................2 Command Line Functions.......................................................................................................3 Viewing a Function..................................................................................................................5 The Return Types of a Function.............................................................................................6 Programming Using Functions.....................................................................................................10 Using Local and Global Variables with Functions.................................................................10 Calling a Function Recursively..............................................................................................12 Loading a Function Automatically.........................................................................................13 Passing Parameters..............................................................................................................15 i Chapter 6: How Functions Work A function is a set of statements that run together to perform a particular task. Functions increase the reusability of code, because you can use the same function multiple times in a program. You invoke a function using the function name. In the Korn shell, when you invoke a function, the shell interpreter transfers program control to the first statement in the function. After the interpreter interprets all the statements in a function, the Korn shell transfers control back to the calling function or to the module that invoked the function. This chapter explains how to use functions in the Korn shell. It also describes how to view and create command line functions. The chapter explains programming with functions using variables and recursion and gives instructions on loading a function automatically. Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Using Functions in the Korn Shell Functions in the Korn shell are similar to the functions of other programming languages, such as C and C++. A Korn shell function is stored in the Korn shell memory, and you can invoke the function using the function name. Unlike a Korn shell program, running a function does not create a separate shell process. The advantages of using a function in a Korn shell program are: Improves processing speed because the function resides in the Korn shell memory. Creates an optimal Korn shell program because repeated code fragments are replaced by calls to the function.
The Structure of a Function in the Korn Shell When you create a function, enclose all the statements to run together in curly braces. A function consists of an optional return statement that specifies the success or failure of a function. The syntax to create a function in the Korn shell is: function name_of_function { statement1 [ [ [statement2] ...] return value ] } Alternatively, you may use this syntax: name_of_function() { statement1 [ [ [statement2] ...] return value ] } Both syntaxes show how to create a function with a name specified in the name_of_function variable. The function name should not contain parentheses. The syntax includes an optional return statement that indicates whether the function executed successfully or not. The return statement is also used to return the function result to the calling Korn shell program. For example, in the UNIX operating system, the who am i builtin command identifies the end user logged in at a terminal. The code for creating a userdefined function that performs the same function as the who am i command is: function user { var=$(who am i) print "$var" } This code creates a function that identifies the end user currently working on a terminal. The var variable displays the name of the user. You run a function by typing the name of the function on the console. A pair of parentheses should succeed the function name. Figure 61 shows how the user function identifies the end user working on a terminal: Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 61: Using the user Function In contrast to programming languages such as C and C++, Korn shell function definitions precede the statement that calls the function. In a Korn shell program that uses a function, the Korn shell function can access the programs variables and the program can access the functions variables. You can also pass parameters to a Korn shell function, by typing them at the command line that invokes the function. However, the parameters that you pass to a Korn shell program from the command line are not available to functions in the Korn shell program. Command Line Functions The Korn shell allows you to create command line functions to perform a specific task. The command line functions are volatile functions. This means that a command line function is deleted when you exit the Korn shell. The syntax for a command line function is: function name_of_function This syntax creates a function with the name specified in the name_of_function command line parameter. After you create a command line function, you can invoke the function by typing the function name at the console. Listing 61 shows a command line function that shows the current date and time: Listing 61: Using the Command Line Function # function week > { > if [[ z $1 ]] > then > date +%c > return 0 > fi > case $1 in > abw) var=$(date +%a) > print "$var";; > wk) var=$(date +%A) > print "$var";; Working with Korn Shell 3 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited > abm) var=$(date +%b) > print "$var";; > mn) var=$(date +%B) > print "$var";; > cen) var=$(date +%C) > print "$var";; > dy) var=$(date +%d) > print "$var";; > dt) var=$(date +%D) > print "$var";; > tm) var=$(date +%T) > print "$var";; > *) print "Please enter the values in correct format\n" > return 1;; > esac } The above listing shows the week function, which displays the current date and time. The week function uses a case statement to handle various options for presenting the results of the date command. The week function also includes options for viewing the current day, date, and time. Table 61 describes the command options for viewing the current day, date, and time: Table 61: Command Options Available with the week Function Command Option Description abw Displays the abbreviated name of a weekday. For example, if the day of the week is Monday, the abw command option displays mon. wk Displays the complete name of a weekday. abm Displays the abbreviated name of a month. For example, if the month is January, the abm command option displays jan. mn Displays the complete name of a month. cen Displays the century as a decimal number. dy Displays the current date. dt Displays the current date. The dt command option displays the current date in the month/date/year format. tm Displays the current time. The tm command option displays the current time in the hour:minute:second format. When you enter the week function with a command option at the command line, the time or date appears in the format specified by the command option. Figure 62 shows the output of Listing 61, as the week function displays the current date and time: Working with Korn Shell 4 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 62: Viewing the Current Date and Time Viewing a Function After creating a command line function, you can view the function name and definition. The builtin Korn shell command, typeset, displays the function definition and name. The typeset includes three options for viewing a command line function: typeset f: Shows the definitions of all the command line functions that have been created in the current Korn shell session. Since the command line functions live only as long as the current session, you cannot view functions created in earlier Korn shell sessions.
typeset +f: Shows just the names of command line functions that have been created in the current Korn shell session.
typeset f fun_name: Shows the definition of the command line function represented by the fun_name parameter.
Figure 63 shows how to use the typeset command to view a command line function definition: Working with Korn Shell 5 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 63: Using the typeset Command The Return Types of a Function The Korn shell uses the return statement to return an integer or string value to a calling program. The return value of a function is stored in the builtin Korn shell variable, $?. The return statement can return an integer value up to 255. Listing 62 shows how to use a return statement to return integer values: Listing 62: Using the return Statement to Return Integer Values #!/bin/ksh function week { if [[ z $1 ]] then var=$(date +%c) return 0 fi case $1 in abw) var=$(date +%a) return 1;; wk) var=$(date +%A) return 2;; abm) var=$(date +%b) return 3;; mn) var=$(date +%B) return 4;; cen) var=$(date +%C) return 5;; dy) var=$(date +%d) return 6;; dt) var=$(date +%D) return 7;; tm) var=$(date +%T) return 8;; *) return 9 ;; esac } # Korn shell program execution starts from here week $1 case $? in Working with Korn Shell 6 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited 0) print "Current date and time is: " print "$var" ;; 1) print "Abbreviated name for current weekday is: " print "$var" ;; 2) print "Complete name for current weekday is: " print "$var" ;; 3) print "Abbreviated name for current month is: " print "$var" ;; 4) print "Complete name for current month is: " print "$var" ;; 5) print "Current century in decimal format is: " print "$var" ;; 6) print "Current day of the month is: " print "$var" ;; 7) print "Current date is: "print "$var" ;; 8) print "Current time is: " print "$var" ;; 9) print "Enter the correct option for the function" print "$var" ;; esac The above listing shows how to use the return statement to view the current date and time. The function parameters are passed through the statement in the Korn shell program that invokes the week function. For each function parameter, the week function returns an integer value. The Korn shell program consists of case control to display the date and time using the Korn shell builtin variable, $?. Figure 64 shows the output of Listing 62 that displays the date and time: Figure 64: Viewing Date and Time You can also return a functions result in a string. To return a function value in a string, enclose the function name in parentheses preceded by the dollar ($) sign. The $ sign attached to a variable denotes the value stored in the variable. Listing 63 shows how a function result can be returned in a string: Listing 63: Returning a Function Result in a String #!/bin/ksh function cmds Working with Korn Shell 7 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited { case $1 in env) echo "The value of builtin variable, ENV, is: $ENV";; home) echo "The value of builtin variable, HOME, is: $HOME" ;; shl) echo "The value of builtin variable, SHELL, is: $SHELL";; mail) echo "The value of builtin variable, MAIL, is: $MAIL";; *) echo "Incorrect parameter";; esac } if [[ z $1 ]] then echo "Please enter a function parameter. The function parameters available with function are env, home, shl, and mail" exit 1 fi val=$(cmds $1) print "$val" The above listing shows the cmds function, which returns the function value in the val string. The cmds function includes a case statement that handles the builtin Korn shell variables ENV, HOME, SHELL, and MAIL. Table 62 describes the Korn shell builtin variables that the cmds function uses: Table 62: Korn Shell BuiltIn Variables in the cmds Function BuiltIn Variable Description ENV Specifies the environment file that the UNIX operating system invokes when the Korn shell starts. HOME Specifies the logon directory for a UNIX user. SHELL Specifies the path for the shell program that currently runs UNIX commands. MAIL Specifies the file where email messages are stored. Figure 65 shows the output of Listing 63, which displays the value of the builtin Korn shell variables and returns the function result in a string variable: Working with Korn Shell 8 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 65: Running Builtin Korn Shell Variables Working with Korn Shell 9 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Programming Using Functions A local variable is accessible within a function while a global variable is accessible to the entire shell program. When programming with functions, you can automatically load a function into a program to improve the performance of a Korn shell program. You can pass parameters between a function and the calling program either by reference or by value. Using Local and Global Variables with Functions In the Korn shell, a function can include both local and global variables. A local variable is accessible only within a function, but a global variable is accessible to the entire shell program. A local variable holds a value within the function where it is defined. Local variables enable you to divide a large program into small modules so that each module can be developed independent of the other. You can use the Korn shell keyword, typeset, to define a local variable. As a local variables scope is restricted to the function where it is defined, you can use the same local variable name in different Korn shell functions. Listing 64 shows how to use the same local variable name with multiple functions in a Korn shell program: Listing 64: Using Local Variables #!/bin/ksh function fun1 { typeset local1 local1="In function, fun1, variable, local1 contains: My name is John" echo $local1 } function fun2 { typeset local1 local1="In function, fun2, variable, local1 contains: My name is Sandra" echo $local1 } local1="In program, variable, local1 contains: My name is Sam" echo $local1 fun1 fun2 The above listing uses two local1 local variables in two functions, fun1 and fun2. The Korn shell keyword, typeset, declares the local1 local variable. This variable is used in the loc Korn shell program, and in the fun1 and fun2 functions. Figure 66 shows the output of Listing 64 that displays the values of local variables: Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 66: Displaying the Values of Local Variables In addition to local variables, you can also define global variables in a function. You can access global variables from any function present in a Korn shell program. You can make a variable global by: Not declaring the variable in the Korn shell program: Allows you to use a variable globally in a Korn shell program. When the Korn shell reads a variable for the first time, it checks whether the variable is declared. If the variable is not declared, the Korn shell assumes it is a global variable.
Not declaring a variable in the function: Allows you to use the variable globally. If a Korn shell program contains a local variable and a global variable with the same name, the local variable takes priority. For example, suppose that a Korn shell program contains both a local variable and a global variable named var. When you run the Korn shell program, the var variable stores the value assigned to the var local variable. Listing 65 shows how to use a global variable in a function: Listing 65: Using Global Variables #!/bin/ksh function fun { echo "In function, fun, value for first command line parameter is: $0\n" var="In function, my name is Jack." } typeset var var="In calling program, my name is John." echo "Value of variable, var, is: $var\n" echo "In calling program, value for first command line parameter is: $0\n" fun echo "Value of variable, var, is: $var\n" echo "In calling program, value for first command line parameter is: $0\n" The above listing uses the var global variable, which is defined in both the fun function, and in the glb Korn shell program. The listing also uses the first command line parameter along with the statement that invokes the function or program. When invoked, the fun function changes the value of the var variable. Figure 67 shows the output of Listing 65, which uses a global variable to access the value of a variable: Working with Korn Shell 11 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 67: Accessing a Global Variable Calling a Function Recursively A function that calls itself is referred to as a recursive function. A recursive function always contain a condition which, when met, stops the functions execution. A recursive function increases CPU overhead because the function increases the number of function calls, but it also allows you to create simple programs with minimal code. Listing 66 shows a recursive function that calculates the factorial of a number: Listing 66: Using a Recursive Function #!/bin/ksh integer prod function fact { integer value=0 integer param=0 if (( $1 == 1 )) then prod=1 else param=`expr $1 1` fact $param value=`expr $1 \* $prod` prod=$value fi } if [[ z $1 ]] then print "Please enter a number\n" exit fi if (( $1 <= 0 )) then print "Please enter a number greater than 0\n" exit fi fact $1 print "factorial of $1 is: $prod\n" The above listing shows the fact recursive function, which calculates the factorial of a specified number. The function also validates the parameters that are supplied at the command line to invoke the Korn shell program. The param variable stores the number for which the factorial is calculated. Every time the function calls itself, the value of the param variable is decremented by one. Figure 68 shows the output of Working with Korn Shell 12 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Listing 66 that displays the factorial of a number: Figure 68: Factorial of a Number Using Recursive Function Loading a Function Automatically Loading a function automatically means that the function definition is saved in a separate location than the location where the calling program is saved. The calling program can make a reference to an automatically loaded function. The function is loaded in the Korn shells memory only when it is called. To load a function automatically, you specify the autoload keyword before the name of the function. To load a function automatically: Create a directory where you can store the function that you want to autoload. For example, you might create a directory in the /usr/lib directory. The commands to create the autoloaded functions directory are: $ cd /usr/lib $ mkdir autoloaded 1. Open the Korn shell environment file, profile, in the /etc directory. Use the Korn shell builtin variables, PATH and FPATH, to autoload a function. The commands that you need to append to the environmental file, profile, are: FPATH=/usr/lib/autoloaded PATH=$PATH:$FPATH export FPATH PATH 2. Store the function that you want to autoload in the /usr/lib/autoloaded directory. For automatic loading, the function name must be the same as the file name. 3. When the Korn shell interpreter reads the autoload keyword, the interpreter searches the shells environment file for the FPATH builtin variable. This variable provides the interpreter with the path to the directory that stores the autoloaded functions. Listing 67 shows how to load a function automatically: Listing 67: Loading a Function Automatically Working with Korn Shell 13 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited #!/bin/ksh integer prod autoload fact if [[ z $1 ]] then print "Enter an integer value\n" exit fi if (( $1 <= 0 )) then print "Error\n" exit fi fact $1 print "The factorial is: $prod\n" The above listing automatically loads the fact function. The listing validates the parameters that are supplied at the command line to the fact function. Listing 68 shows the function to store in the directory specified by the FPATH variable: Listing 68: Creating a Function to be Automatically Loaded function fact { integer value=0 integer param=0 if (( $1 == 1 )) then prod=1 else param=`expr $1 1` fact $param value=`expr $1 \* $prod` prod=$value fi } The above listing shows the fact function, which calculates the factorial of the number specified by the $1 command line parameter. The prod variable stores the factorial of the number specified in the function. Since a function to autoload should be saved in a file with the same name as the function, you store the fact function in a file named fact. Figure 69 shows the output of Listing 67, for which Listing 68 specifies the function: Working with Korn Shell 14 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 69: Factorial of a Number Using AutoLoaded Function Passing Parameters You can pass parameters between a function and a calling program either by reference or value. Passing parameters by reference means that the address of a parameter is passed between the calling program and the function. Parameters that you want to pass by reference should be preceded by the Korn shell keyword, nameref, in the body of the function. The parameter should be specified without the dollar ($) sign. Listing 69 shows how to pass parameters by reference, exchanging the values of two parameters: Listing 69: Passing Parameters by Reference #!/cathy/bin/ksh function swap { integer t nameref m=$1 nameref n=$2 t=$m m=$n n=$t } if [[ z $1 && z $2 ]] then print "Error, both the parameters are missing\n" exit fi if [[ z $1 || z $2 ]] then print "Error, one of the parameters is missing\n" exit fi a=$1 b=$2 print "Before function call, the values are val1: $a and val2: $b" swap a b print "After function call, the values are val1: $a and val2: $b" The above listing shows how to exchange the values of the $1 and $2 command line parameters. The listing also checks whether both parameters are supplied. The $1 and $2 command line parameters are stored in the a and b variables, respectively. The addresses of the variables are passed to the swap function. Figure 610 shows the output of Listing 69 that swaps the values of two parameters: Working with Korn Shell 15 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited Figure 610: Swapping Parameter Values Unlike passing parameters by reference, passing parameters by value passes the actual variable. If a parameter is passed by reference, it acts as a global variable. A parameter passed by value acts as a local variable. If you are working with a complex program that needs global variables, passing a parameter by reference is preferred. Working with Korn Shell 16 Reprinted for ibmramanramachandran@in.ibm.com, IBM SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited