我有一个 ksh93 脚本,正在从 AIX 6.1 迁移到 AIX 7.1
它在 7.1 上失败,但在 6.1 上工作正常。这是重要部分的片段。
integer f_count=0
. . .
. . .
. . .
if [[ ($f_count*$sleep_interval%$alarm_interval -eq 0 ) && $f_count > 0 ]]
then
当它达到“如果”时我得到
第 191 行:*10%300:算术语法错误
我决定通过在命令提示符下键入此内容来简化它。
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
为了显示它是 AIX 6.1 上的 ksh93,我这样做了。
asdlkfjasd
-ksh93: asdlkfjasd: not found.
如果我移动 0 值,使其不是第一个,它就会按预期工作。
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
这将解决我的问题,因为我知道原始方程中的第二个和第三个变量永远不会为 0。
这是否显示了 AIX 7.1 的错误?
答案1
看来您在 ksh93 中发现了一个错误。
我可以用以下命令重现它(ksh93u+):
$ x= ksh -c '[[ 0*1 -eq 5 ]]'
ksh: *1: arithmetic syntax error
没关系:
ksh -c '[[ " 0*1" -eq 5 ]]'
尽管。它似乎已在ksh93v-
(测试版)中修复,因为我无法在那里重现它。
无论如何,我会使用:
if ((f_count * sleep_interval % alarm_interval == 0 && f_count > 0)); then
一些注意事项:
- inside
[[...]]
,>
用于字符串比较(其中10
小于 2,并且根据区域设置,-1
可能大于 0)。用于-gt
数值比较(尽管最好使用((...))
)。 避免在算术表达式内扩展变量,例如使用
x
而不是$x
.例如,比较:$ x=-1 ksh -c '((-$x > 0))' ksh: --1 > 0: assignment requires lvalue
和
$ x=-1 ksh -c '((-x > 0))' $
或者:
$ x=1+1 ksh -c 'echo "$(($x * 2)) $((x * 2))"' 3 4
答案2
看起来 ksh 确实对算术展开做了不同的事情;为了解决这个问题,我将明确使用算术替换,它在 AIX 6 和 AIX 7 上的行为都符合预期:
...
if [[ ( $((f_count * sleep_interval % alarm_interval)) -eq 0 ) && $f_count -gt 0 ]]
...
答案3
也许答案很简单;当算术表达式开头的变量扩展到 0(零)时,您会遇到问题。这是 KSH 条件表达式中 -eq 的左操作数 - -eq 是数字比较,运算符期望一个数字作为其左操作数。
当扩展/计算操作数时,运算符需要执行三个步骤:a)扩展变量,b)去除前导零,c)计算表达式;按照这个顺序,你就会得到观察到的问题。
如果旧的 Shell 版本按以下顺序执行:a) 展开变量,b) 求值表达式,c) 去除前导零;那么你就不会看到问题