f



very strange ksh behavior

This is a very strange problem.

 $ while read line
> do
>    rc=$(echo $line | awk '{ print $4 }')
>    echo BEFORE rc is $rc
>    if [ "$rc" -ne 0 ]; then echo " ERROR rc nonzero rc is $rc"; fi
>    echo AFTER  rc is $rc
> done
extract4 status: file=file1.txt rc=0 realcount=488
BEFORE rc is rc=0
AFTER rc is 0
extract4 status: file=file2.txt rc=2 realcount=223
BEFORE rc is rc=2
 ERROR rc nonzero rc is 2
AFTER rc is 2
extract4 status: file=file3.txt rc=0 realcount=992
BEFORE rc is rc=0
AFTER rc is 0
 $ uname -a
AIX dscnd002 3 5 00280FAA4C00

When I pinpoint the problem,

 $ rc='rc=22'
 $ echo $rc
rc=22
 $ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
 ERROR nonzero rc rc is 22
 $ echo $rc
22
 $ rc='rc=0'
 $ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
 $ echo $rc
0
 $

Why is ksh behaving like this?? If rc has a string ("rc=0") then that
is a nonzero value, right?

There are times when a strong drink is required. Either for me or to
pour all over a computer.
0
4/7/2010 9:54:50 PM
comp.unix.shell 15484 articles. 2 followers. Post Follow

5 Replies
1407 Views

Similar Articles

[PageSpeed] 7

2010-04-7, 14:54(-07), Sam:
[...]
> Why is ksh behaving like this?? If rc has a string ("rc=0") then that
> is a nonzero value, right?
[...]

No "rc=0" is a numeric expression, which is an assignment of the
"rc" variable to 0, which resolves to 0.

$ echo $((rc=0))
0
$ echo $rc
0

ksh (at least the AT&T and public domain implementations) is
special in that, [ ... -ne ... ] expands the '...' numeric
expressions. Other shells usually require numericalconstants.
Both behaviors are allowed by POSIX. Best is to avoid
non-numeric constants. So use the "!=" string comparison
operator instead of the numerical "-ne".

-- 
Stéphane
0
Stephane
4/7/2010 10:07:40 PM
Sam <sam.n.seaborn@gmail.com> writes:


>When I pinpoint the problem,

> $ rc='rc=22'
> $ echo $rc
>rc=22
> $ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
> ERROR nonzero rc rc is 22
> $ echo $rc
>22
> $ rc='rc=0'
> $ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
> $ echo $rc
>0
> $

>Why is ksh behaving like this?? If rc has a string ("rc=0") then that
>is a nonzero value, right?

It is not a numerical value so the behaviour is undefined.  

$ rc=foo
$ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
$ echo $rc
foo

(Both "sh" in Solaris and ksh93 behave the same way)

Casper
-- 
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
0
Casper
4/8/2010 8:55:05 AM
2010-04-08, 08:55(+00), Casper H.S  Dik:
[...]
> It is not a numerical value so the behaviour is undefined.  
>
> $ rc=foo
> $ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
> $ echo $rc
> foo
>
> (Both "sh" in Solaris and ksh93 behave the same way)
[...]

There are at least two sh's on Solaris: the Bourne shell and a
POSIX shell based on ksh.

The Bourne shell (/bin/sh no Solaris versions up to 10 at least)
and ksh don't behave the same.

ksh expands the content of $rc as a numeric expression. So in

foo=1+1
rc=foo
[ "$rc" -ne 0 ]

will return true, so would [ "$rc" -eq 2 ].

sh uses strtoll to convert the string to a number, so for "foo"
would understand "0", for "1+1" would understand "1".

bash and zsh do checks on the validity of the number, so would
return an error. You'll probably get different behaviors
depending on what base the numbers are expressed in.

-- 
Stéphane
0
Stephane
4/8/2010 11:15:50 AM
Stephane CHAZELAS <stephane_chazelas@yahoo.fr> writes:

>2010-04-08, 08:55(+00), Casper H.S  Dik:
>[...]
>> It is not a numerical value so the behaviour is undefined.  
>>
>> $ rc=foo
>> $ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
>> $ echo $rc
>> foo
>>
>> (Both "sh" in Solaris and ksh93 behave the same way)
>[...]

>There are at least two sh's on Solaris: the Bourne shell and a
>POSIX shell based on ksh.

I've tested /bin/sh (before it was ksh93) and ksh93.

ksh88 is indeed different (/usr/xpg4/bin/sh):

$ rc=foo
$ if [ $rc -ne 0 ]; then echo " ERROR nonzero rc rc is $rc"; fi
ksh: foo: bad number


Apparently, ksh93 works more like the old sh.

>The Bourne shell (/bin/sh no Solaris versions up to 10 at least)
>and ksh don't behave the same.

>ksh expands the content of $rc as a numeric expression. So in

>foo=1+1
>rc=foo
>[ "$rc" -ne 0 ]

>will return true, so would [ "$rc" -eq 2 ].

except when foo isn't a variable in which case "$rc" evaluates
to 0.

>sh uses strtoll to convert the string to a number, so for "foo"
>would understand "0", for "1+1" would understand "1".

>bash and zsh do checks on the validity of the number, so would
>return an error. You'll probably get different behaviors
>depending on what base the numbers are expressed in.

And so does ksh88.

Casper
-- 
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
0
Casper
4/8/2010 12:14:35 PM
2010-04-08, 12:14(+00), Casper H.S  Dik:
[...]
>>foo=1+1
>>rc=foo
>>[ "$rc" -ne 0 ]
>
>>will return true, so would [ "$rc" -eq 2 ].
>
> except when foo isn't a variable in which case "$rc" evaluates
> to 0.
[...]

foo is an unset variable which expands the same as an empty
variable, and in numeric contexts, the empty string means 0.
It's different from the Bourne shell even if it leads to the
same result in this very case.

unset foo
rc='2*foo+1'
[ "$rc" -eq 1 ]
is true in ksh

-- 
Stéphane
0
Stephane
4/8/2010 12:44:21 PM
Reply: