Subject: /bin/sh vs. /bin/ksh arithmetic expressions....
To: NetBSD Userlevel Technical Discussion List <tech-userlevel@NetBSD.ORG>
From: Greg A. Woods <firstname.lastname@example.org>
Date: 06/17/2004 15:46:25
I was "surprised" to find that /bin/sh and /bin/ksh have very different
arithmetic expression syntax.
Integer constants may be specified with arbitrary bases
using the notation base#number, where base is a decimal
integer specifying the base, and number is a number in the
However /bin/sh treats a leading zero as an indication the number is in
This lead me to the following in P1003-2001/SuSv3:
Next, the shell shall treat this as an arithmetic expression and
substitute the value of the expression. The arithmetic expression
shall be processed according to the rules given in "Arithmetic
Precision and Operations", with the following exceptions:
* Only signed long integer arithmetic is required.
* Only the decimal-constant, octal-constant, and
hexadecimal-constant constants specified in the ISO C standard,
Section 18.104.22.168 are required to be recognized as constants.
* The sizeof() operator and the prefix and postfix "++" and "--"
operators are not required.
* Selection, iteration, and jump statements are not supported.
As an extension, the shell may recognize arithmetic expressions
beyond those listed. The shell may use a signed integer type with a
rank larger than the rank of signed long. The shell may use a
real-floating type instead of signed long as long as it does not
affect the results in cases where there is no overflow. If the
expression is invalid, the expansion fails and the shell shall write
a message to standard error indicating the failure.
So I guess ksh is the odd man out here, though The KornShell book on
p.307 agrees with the pdksh implementation in how different bases should
be specified, so in terms of standardising existing practices the good
old POSIX boys failed miserably yet again.
So, I guess it's fair to have /bin/ksh follow the real Ksh, and for
/bin/sh to follow POSIX in this case, though sh(1) is sorely lacking on
any and all pertinent details about Arithmetic Expressions (we can't
expect everyone to have a copy of SuSv3 handy!).
On the other hand /bin/sh (at least on 1.6.2_STABLE) seems to have some
kind of parsing problem with recognizing operators when there are no
non-digit tokens surrounding them:
$ /bin/sh -c 'echo $((06170718+10000))'
arithmetic expression: syntax error: "06170718+10000"
$ /bin/ksh -c 'echo $((06170718+10000))'
However so long as there is a non-digit token before the operator it's
happy without any whitespace (just operating with different base
$ /bin/sh -c 'echo $(($(date +%m%d%H%M)+10000))'
# /bin/ksh -c 'echo $(($(date +%m%d%H%M)+10000))'
Is this a bug? (As far as I can tell SuSv3 is somewhat silent on the
lexical interpretation of arithmetic expressions.) Is this still a bug
in -current? Should I file a PR?
Greg A. Woods
+1 416 218-0098 VE3TCP RoboHack <email@example.com>
Planix, Inc. <firstname.lastname@example.org> Secrets of the Weird <email@example.com>