[[ 0*10%300 ]] works on AIX 6.1 but not on AIX 7.1 (ksh)

aixkshtest

I have a ksh93 script that I'm migrating from AIX 6.1 to AIX 7.1

It's failing on 7.1 but works fine on 6.1. Here's a snippet of the important parts.

integer f_count=0
   . . . 
   . . . 
   . . . 
if [[ ($f_count*$sleep_interval%$alarm_interval -eq 0 ) && $f_count > 0 ]]       
then

When it hits the "if" I get

line 191: *10%300: arithmetic syntax error

I decided to simplify it by typing this at the command prompt.

AIX 7.1> integer x=1          
AIX 7.1> [[ $x*10%300 -eq 0 ]]
AIX 7.1> print $?
1
AIX 7.1> integer x=0          
AIX 7.1> [[ $x*10%300 -eq 0 ]]
-ksh93: *10%300: arithmetic syntax error


AIX 6.1> integer x=1          
AIX 6.1> [[ $x*10%300 -eq 0 ]] 
AIX 6.1>  print $?                                                                                        
1
AIX 6.1>  integer x=0                                                           
AIX 6.1>  [[ $x*10%300 -eq 0 ]] 
AIX 6.1>  print $?                                                                                        
0

To show it's ksh93 on AIX 6.1 I did this.

asdlkfjasd
-ksh93: asdlkfjasd: not found.

If I move the 0 value so it's not first, it works as expected.

AIX 7.1> integer x=1            
AIX 7.1> [[ 10*$x%300 -eq 0 ]]  
AIX 7.1> print $?             
1
AIX 7.1> integer x=0           
AIX 7.1> [[ 10*$x%300 -eq 0 ]]  
AIX 7.1> print $?             
0

This will fix my issue as I know the 2nd and 3rd variables in my original equation will never be 0.

Is this showing an AIX 7.1 bug?

Best Answer

Looks like you've found a bug in ksh93.

I can reproduce it (ksh93u+) with:

$ x= ksh -c '[[ 0*1 -eq 5 ]]'
ksh: *1: arithmetic syntax error

It's OK with:

ksh -c '[[ " 0*1" -eq 5 ]]'

though. And it seems it was fixed in ksh93v- (beta) as I can't reproduce it there.

Anyway, I would use:

if ((f_count * sleep_interval % alarm_interval == 0 && f_count > 0)); then

A few notes:

  • inside [[...]], > is for string comparison (where 10 is less than 2 and depending on the locale, -1 may be greater than 0). Use -gt for numerical comparison (though it's better to use ((...))).
  • avoid expanding variables inside arithmetic expressions, as in, use x instead of $x. For instance, compare:

    $ x=-1 ksh -c '((-$x > 0))'
    ksh: --1 > 0: assignment requires lvalue
    

    with

    $ x=-1 ksh -c '((-x > 0))'
    $
    

    Or:

    $ x=1+1 ksh -c 'echo "$(($x * 2)) $((x * 2))"'
    3 4
    
Related Question