Discussion:
[ast-developers] ksh -u or 'set -o nounset' behaviour for undefined positional parameter like $1.
lijo george
2015-06-01 12:36:43 UTC
Permalink
It seems ksh does not treat unset positional parameters like "$1" as an
error while using the "-u" or "nounset" option.

Here's a test script which shows the behaviour for undefined positional
parameters

I've tried this with ksh versions from 2011 onwards and the behaviour is
same.(2011-02-08, 2012-08-01, 2013-10-10

$ cat test.ksh
#!/bin/ksh93 -u

arg1=$1

echo "This message should not be printed unless there is an argument to
this script."

$ ./test.ksh
This message should not be printed unless there is an argument to this
script.
$

Browsing through the Changelog, I see that there is an old reference which
might be related.

09-05-12 To conform with POSIX, the -u option only checks for unset variables
and subscript elements rather than checking for all parameters.

Also from the opengroup shell specification for the -u option given below,
it looks like it might be a bug.

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_25
*-u*When the shell tries to expand an unset parameter other than the '@'
and '*' special parameters, it shall write a message to standard error and
shall not execute the command containing the expansion, but for the
purposes of setting the '?' special parameter and the exit status of the
shell the command shall be treated as having been executed and returned an
exit status of between 1 and 125 inclusive. A non-interactive shell shall
immediately exit. An interactive shell shall not exit.Could someone please
confirm whether this is is a bug.

Thanks,
Lijo
lijo george
2015-06-03 22:28:58 UTC
Permalink
Going through the latest changelog, I see that there was a mention of this
issue.

13-04-04 A bug in which an unset variable error with set -u on did not
terminate the current script has been fixed.

Trying to isolate the fix for this, I saw that in the varsub() function in
macro.c,
there is a check added for this case.

if(!v && sh_isoption(mp->shp,SH_NOUNSET))
{
d=fcget();
fcseek(-1);
if(!strchr(":+-?=",d))
errormsg(SH_DICT,ERROR_exit(1),e_notset,ltos(c));
}

But even with this change, the issue is still happening.

Tracing the code, I see that the variable d will be '\0' and this is being
checked in the strchr
function, causing strchrto return true. Hence the errormsg function is not
being called.

Could someone please confirm whether this is the issue.

Thanks,
Lijo
Martijn Dekker
2015-06-07 20:37:11 UTC
Permalink
Post by lijo george
It seems ksh does not treat unset positional parameters like "$1" as
an error while using the "-u" or "nounset" option.
[...]
Post by lijo george
Could someone please confirm whether this is is a bug.
It is. As the POSIX spec says, only "$@" and "$*" are supposed to be
exempt from 'set -u' checking, so $1, $2, etc. should not be exempt.
I've also confirmed that this is how other current shells act, including
bash, dash, mksh, zsh and yash.

Older ksh93 versions, at least '1993-12-28 s+', had the opposite bug:
$1, $2, etc. were being checked (correctly), but so were "$@" and "$*"
(incorrectly). This has necessitated annoying workarounds to get a
script to function with "set -u" since you cannot simply do something
like: command "$@". But now it looks like they went too far in fixing
this issue.

Thanks,

- Martijn (not a ksh developer)

Loading...