Strange KSH behaviour - any comments?

As you are probably aware, $# indicates the number of parameters passed into a korn shell script. But this appears to hang around for
sunsequent runs...????

A simple script:-
#!/usr/bin/ksh
echo "#parameters $#"
echo "\$1 $1"
echo "\$2 $2"

I run the script with 0 parameters (all fine)
# . par.ksh
#parameters 0
$1
$2

Now run it passing 2 parameters (all fine)
# . par.ksh aaa bbb
#parameters 2
$1 aaa
$2 bbb

Now run it again with no parameters (and it still thinks there are 2)!
# . par.ksh
#parameters 2
$1 aaa
$2 bbb

If I add set -- (to unset positional parameters) it works!
But I would have though that $# gets set every time its run,

Any ideas anyone ?????

Hi!

I have tried what u did in AIX5.3, that uses ksh and it worked well.

root@bbb:/> ./teste.sh ola
#parameters 1
$1 ola
$2
root@bbb:/> ./teste.sh ola bla
#parameters 2
$1 ola
$2 bla
root@bbb:/> ./teste.sh ola bla edas
#parameters 3
$1 ola
$2 bla
root@bbb:/> ./teste.sh
#parameters 0
$1
$2
root@bbb:/>

Thanks for that, Hmmmmm,

I may have to raise a call (Its on Solaris 10).

ok! hope that would help

Gsw_aix, you're dot including - so you are running all your scripts in the current shell.
Gfca, on the other hand, is running each script in separate child shells.

Exactly this - once the script is run in the currect shell, once in a daughter shell - is reason for the different results.

The line ". ./x.ksh par1 par2" does the following: it starts in the current shell the script x.ksh and passes two parameters. These parameters are passed not to the script but to the process which runs the script. This process is the current process - our login shell. When the script is run again in the same process the two parameters passed to this process are still there. They can be displayed even in the commandline:

# cat x.ksh
#! /bin/ksh
print - "$? parameters have been passed"
exit 0

# print - $?
0                 # there are no parameters

# . ./x.ksh par1 par2
2 parameters have been passed

# print - $?
2                 # there still are the two parameters

# . ./x.ksh
2 parameters have been passed

On the other hand if we run "./x.ksh par1 par2" we first start a new process, pass the two parameters to this new process, run the script and end the process again. If we cll it agin, another(!) new process is created, which does of course know nothing about the first process and its environment.

See also this thread: How to clear $1 when dot-running a script.

I hope this helps.

bakunin

Hi i worked on linux with the same script, i didn't find wrong with the KSH behaviour

[saik@lnx02 mp]$ ./test.ksh
#parameters 0
$1
$2
[saik@lnx02 mp]$ ./test.ksh 111 222
#parameters 2
$1 111
$2 222
[saik@lnx02 mp]$ ./test.ksh 111 222 333
#parameters 3
$1 111
$2 222
[saik@lnx02 mp]$ ./test.ksh 111
#parameters 1
$1 111
$2
[saik@lnx02 mp]$ ./test.ksh
#parameters 0
$1
$2
[saik@lnx02 mp]$

Sai Kumar

I tested the problem originator's code on Solaris 10 and got the same results as the originator using both /usr/bin/ksh and /xpg4/usr/bin/ksh

Next I tested your code on ksh93 (version t- 6/14/2008 on Interix.i386 V6) and noticed the following:

  • Your sample code uses $? to "print the number of parameters passed" . My understanding of the ksh programming language and shell is that $? returns the decimal value returned by the last executed command. and $# returns the number of positional parameters.
  • Your sample code (x.ksh) contains an "exit 0". When executed within the current shell context this will close the shell i.e. exit the shell.

Here are my results for ksh93:

$ cat x.ksh
#!/usr/bin/ksh93
print - "$# parameters have been passed"
$ . ./x.ksh 1 2
2 parameters have been passed
$ . ./x.ksh
0 parameters have been passed
$

The problem appears to be specific to Solaris.