7.4 Korn Shell Functions

10. Korn Shell Functions
A function is a special definition of some algorithm that is assigned to a 
(variable-like) name for use by a shell script.  Functions that are only used 
inside one script can be defined at the beginning of the script.  The 
function starts with the reserved word "function", a name for the function,  
and the code which is contained in "{   }" braces.  Bourne shell functions 
are declared by function name followed immediately by "()" and then the code 
contained in "{   }" braces.

11. An Example:
	$ cat showfun
	#! /bin/ksh						#! /bin/sh
	# this script shows where function can be declared.
	print "Entering the script showfun"

	function local1		 or				local1()
	{	
		print "We are in the local1 function"
	}

	print "In showfun script"
	local1
	
	# can we call local2 before it is written?
	print "Can we call local2 before it is written?"
	local2
	
	# now declare local2
	print "Local2 is being declared."

	function local2			or			local2()
	{
		print "This is function local2"
	}

	print "Script showfun after the declaration of local2"
	local2
	$ showfun
	Entering the script showfun
	In showfun script
	We are in the local1 function
	Can we call local2 before it is written?
	showfun:  local2:  not found
	Local2 is being declared.
	Script showfun after the declaration of local2
	This is function local2

12. A function may also be declared as part of an initialization file 
like .profile or .kshrc.  If the function is created in these files and will 
be used outside these files, the function must be exported via 
typeset -fx functionname .  

Functions may also be placed in a directory and then autoloaded in scripts 
when needed.  Such functions are defined and contained in their own files 
using the same name.  If a function is to be autoloaded, the FPATH 
variable must be defined to include the path name of the directory 
containing the function and the FPATH variable itself should be 
exported.  The Bourne shell does not have an autoload feature nor does 
it use the FPATH variable.  i.e.

	$ ls functions
	showfun
	$ tail -2 .profile
	FPATH=":~/functions:" ; export FPATH
	autoload showfun
	$ typeset -f
	showfun

13. A function can be used anywhere a script can be used.  A function 
can be called either inside a script or at the command line.  It must be 
defined (declared) before it can be used.  Do this either by including the 
body of the function in the script or by autoloading the function.

If the function is run at the prompt, the function should be defined in 
the startup file (.profile or .kshrc) or the FPATH 
variable should be set and the function be defined in a file of the same 
name in a directory specified by FPATH. 

14. Input to functions
Values may be explicitly passed to a function by calling the function with 
some arguments.  These arguments are then accessible inside the function 
using the positional (numbered) parameters.  The positional parameters at 
the script level are not the same and separate from the positional parameters 
inside the function except when the function is invoked with "$@" as its 
arguments.
	
Arrays may be passed to a function, however, the values of the array are 
converted to positional parameters for the function and the array elements 
are then accessed as positional parameters.  If an array and a single value 
are passed to a function then we have:
	$ cat arraypassing
	function arraypassing
	{	
		i=1
		for pos in "$@"
		do
			print $i is $pos
			(( i = i + 1 ))
		done
	}
	
	$ . arraypassing
	$ typeset -f
	showfun
	arraypassing
	$ set -A arr one two three
	$ value=four
	$ ksh arraypassing $value ${array[*]}
	1 is four
	2 is one
	3 is two
	4 is three

15. Returning values from functions
	(1) The return statement allows a function to pass back 
an integer value between 0 and 255.  This value is stored in the $? 
variable as far as the calling program is concerned and must be read 
immediately after control is returned to the calling program.
	
	$ cat returntest
	# declare or define the function
	function callfunction
	{	
		i=1
		for pos in $*
		do
			print $i is $pos
			(( i = i + 1 ))
			return 10
		done
	}
	# invoke or call the function
	set -A arr one two three
	value=four
	callfunction $value ${array[*]}
	print $?
	print "leaving returntest"
	$ ksh returntest
	1 is four
	10
	leaving returntest
	$ 

	(2)  Use $( ... ) [ command substitution ]  to capture other, 
additional, non-integer output from a function.  Just assign the output of 
the function to a variable.

	$ cat fr
	# this is an example of the function returning
	function bunch
	{
		print from the bunch function
		date
	}
	# define the variable
	from=$(bunch)
	print this is $from
	$ ksh fr
	this is from the bunch function Sun Feb 28 09:10:11 PST 1999
	
	(3) Use temporary files to store information to be passed back 
to the calling program.

16.  Local and global variables
	Any variable declared inside a function (using typeset or not) 
is local to that function in the Korn shell.  (The Bourne shell functions 
do not have local variables).  If a variable is declared outside the 
function, the variable is global or accessible throughout the rest of the 
script.  If a variable is declared twice, once inside a script and once 
inside a function, the declaration inside the function hides the outer 
declaration.

	$ cat from1		$ cat from2
	x=10			x=10
	function fun1		function fun2
	{			{
		typeset x		x=40
		x=40			print $x
		print $x	}
	}					
	fun1			fun2
	print this is $x	print this is $x
	$ ksh from1		$ ksh from2
	40			40
	this is 10		this is 40
	


Questions? Robert Katz: rkatz@ned.highline.edu
Last Update February 26, 2002