AIX UNIX (kshell) to Linux Shell Script Migration.

Another thing.

If testing something like this (contents of test.sh )
(This code is not inside a loop.)

var3=1
case $var3 in
  1) var1=1
     break ;;
  2) var1=1
     var2=2
     break ;;
  *) echo "Error" ;;
esac

The thing is that when executing this code with ksh (RHEL 6.5) there's no error message from the shell.

But when executing with bash there's an error message when case has to evaluate a condition with break . When executed with ksh or sh , there's no error message.

[root@xxxx]# bash test.sh
test.sh: line 5: break: only meaningful in a `for', `while', or `until' loop
[root@xxxx]# ksh test.sh
[root@xxxx]# sh test.sh

As far as I know, break it has sense only when there's a loop. But since there's no error message for ksh and sh it looks like the behaviour for case is different from bash .

case syntax without break works fine in ksh and sh , with no error messages. Same with bash , as expected.

Any thoughts about this behaviour?

This is probably the same behaviour in ksh-AIX but I couldn't access a machine to test it right now.

If there really is no loop to break from, then I suspect that ksh is just ignoring the statement. The end of each case section is the ;; so logically I suppose it all hangs together.

I've had a go on AIX 5.1 & 6.1 and it just ignores the break statement. On RHEL 6 with ksh it is ignored, but the error you find pops up with bash

Robin

So, i take it, this is because "[" is a shell builtin. (Which it is indeed - i had the wrong impression that "[" is external and "[[" is the builtin, but i learned otherwise through experiment. In fact "[" is a builtin and "[[" is a reserved word, according to my system shell on AIX, a ksh88.)

This seems to be in line with the following analogous lines, where "x" and "$x" can be used interchangeably:

x=5 ; let x=x+1
x=5 ; let "x = x + 1"
x=5 ; (( x += 1 ))
x=5 ; echo $(( x ))

I wonder how the parsing process of the ksh works so that this is only the case for integers (or - for the shell obviously being the same - strings which evaluate to integers). One would think that variables either get expanded or not, but it would not depend on their content if they are.

bakunin

The standards say:

It looks like bash writes a warning message to stderr (but does not affect the exit status) in this case while ksh behaves as specified by the standards (silently ignoring the fact that your code is issuing a break when there is no enclosing loop).

1 Like

I haven't dug into the source of any of these shells, but my impression is not that the shell looks at the contents of the variables, but the context of how the variable is used. In an arithmetic evaluation, when a number is expected and a non-numeric string is seen I would guess that it looks for a variable of that name and substitutes it if it works. Note that let expr , (( expr )) , $(( expr )) , and [ n1 -eq|-ne|-lt|-le|-ge|-gt n2 ] are all arithmetic evaluations.

PS. Even when test and [ are built-ins, they also have to be available as stand alone utilities (so they can be used with things like find dir -exec test expr \; ) like other standard utilities.