Kornshell function declarations

Over the years I have seen and maintained many kornshell scripts written by DBAs, and programming style can provoke strong reactions on the "right" way of doing things.

In this article, I will explain the different ways in which functions can be defined in Kornshell and explain why I personally prefer one method over another.

Declaring functions

The two methods in Kornshell for declaring functions are shown below.

The first, is to use the dedicated Function keyword:

function helloWorld
{ 
  echo "Hello World" 
}

The second way, known as the POSIX Standard, is to use empty parentheses () :

goodbyeWorld()
{ 
  echo "Goodbye World" 
}

Which method to use

When deciding which particular method to use to declare your functions there is one important difference that you must be aware of. The parentheses method does not support local variables.

Here's a simple test:

#!/bin/ksh

function k
{
  kv1=kv1
  typeset kv2=kv2
  echo inside k
  echo "  kv1: $kv1"
  echo "  kv2: $kv2"
}

p()
{
  pv1=pv1
  typeset pv2=pv2
  echo inside p
  echo "  pv1: $pv1"
  echo "  pv2: $pv2"
}

k
echo outside k
echo "  kv1: $kv1"
echo "  kv2: $kv2"
p
echo outside p
echo "  pv1: $pv1"
echo "  pv2: $pv2"

And the output generated:

inside k
  kv1: kv1
  kv2: kv2
outside k
  kv1: kv1
  kv2:
inside p
  pv1: pv1
  pv2: pv2
outside p
  pv1: pv1
  pv2: pv2

From this we can see that  the local variable kv2 is defined only within the function k and not available outside the function, whereas local variable pv2 is still defined when function p exits.

Although this may seem trivial, tracking down a bug caused by this behaviour will be very difficult. As a result, my advice would be to always use the function keyword to declare your functions.

A final word of advice regarding function naming

When reading and maintaining code written by others it can be very difficult at times to know whether a a line of code refers to a user-defined function or an external command. For example, is the following line of code using a function or a command?

columns "$LIST_OF_DATABASES"

(In case you're wondering, it must be a user defined function, as the external command for printing columns is "column" - without the "s").

To make your code more readable, I suggest prefixing every function you define with "FN_" - something I borrowed from my earliest programming days writing programs in BBC Basic!

Isn't this much clearer?

FN_columns "$LIST_OF_DATABASES"

 

Thanks! You've already liked this