KSH - different syntax for function

Hi,

I wanted to know what's the difference between the below two syntax used for writing ksh function:

e.g. 1
------

 
function fn1
{
echo "Hello World"
}

e.g. 2
------

 
fn1 ()
{
echo "Hello World"
}

-dips

The first is the more powerful KSH style function. The second is the Bourne style POSIX compliant version. The first form can have local variables and traps and $0 is set to the name of the function instead of the shell plus it supports recursion.

Hi Scrutinizer,

Can you please explain the below in detail? as I didn't quite get it! :frowning:

I tried calling function within itself

fn2 ()
{
echo "Hello World"
fn2
}
fn2

Its able to recursively call itself within itself, the thing is that I get Segmentation fault (core dumped) message.

Also I tried to include trap command inside the function as below

fn2 ()
{
        echo "Hello World"
        var=0
        while [ $var -le 3 ]
        do
                trap "echo 'Hello'" INT
                var=$(( $var + 1 ))
                echo $var
                sleep 5
        done
}

and fn2 was able to trap crtl-c.

Thanks for your patience. Please excuse me if I mis-interpreted something.

-dips

Hi dips_ag,

Here is an example of the difference for local variables and $0, but perhaps that was already clear:

#!/bin/ksh
function f1
{
  f1v1=f1v1
  typeset f1v2=f1v2
  echo inside f1
  echo "f1v1: $f1v1"
  echo "f1v2: $f1v2"
  echo "\$0: $0"
}

f2()
{
  f2v1=f2v1
  typeset f2v2=f2v2
  echo inside f2
  echo "f2v1: $f2v1"
  echo "f2v2: $f2v2"
  echo "\$0: $0"
}

f1
echo outside f1
echo "f1v1: $f1v1"
echo "f1v2: $f1v2"
f2
echo outside f2
echo "f2v1: $f2v1"
echo "f2v2: $f2v2"

Output:

inside f1
f1v1: f1v1
f1v2: f1v2
$0: f1
outside f1
f1v1: f1v1
f1v2:
inside f2
f2v1: f2v1
f2v2: f2v2
$0: ./test
outside f2
f2v1: f2v1
f2v2: f2v2

========================
The trap that you set inside the POSIX function is a global trap. Have a look at this example about the difference between local and global trap:

#!/bin/ksh
function fn3
{
  trap 'echo "You triggered the trap that was set inside function fn3"' INT
  echo "sleeping 30 seconds inside fn3"
  sleep 30
}

fn4()
{
  trap 'echo "You triggered the trap that was set inside function fn4"' INT
  echo "sleeping 30 seconds inside fn4"
  sleep 30
}

trap 'echo "You triggered the trap that was set outside the function"' INT
fn3
echo "sleeping 30 seconds outside"
sleep 30
fn4
echo "sleeping 30 seconds outside"
sleep 30

Output, while pressing ctrl-C in the various stages:

sleeping 30 seconds inside fn3
^CYou triggered the trap that was set inside function fn3
You triggered the trap that was set outside the function
sleeping 30 seconds outside
^CYou triggered the trap that was set outside the function
sleeping 30 seconds inside fn4
^CYou triggered the trap that was set inside function fn4
You triggered the trap that was set inside function fn4
sleeping 30 seconds outside
^CYou triggered the trap that was set inside function fn4

===

About recursion: the difference lies in the use of local and global contexts. E.g. the use of local variables is essential for recursion to work properly, which is not possible with the POSIX style function in ksh..

S.

Thanks Scrutinizer for the detail explanation.

-dips