我在Shellcheck.net Wiki中找到了有用的信息,我引用:
重击:
for ((init; test; next)); do foo; done
POSIX:
: "$((init))"
while [ "$((test))" -ne 0 ]; do foo; : "$((next))"; done
尽管要注意,i++
不是POSIX,所以必须将其翻译为i += 1
或i = i + 1
。
因此,可以使用如下规则将POSIX方式重写问题中的上述脚本:
#!/bin/sh
: "$((i=1))"
while [ "$((i != 0))" -ne 0 ]
do
echo "$i"
: "$((i = i + 1))"
done
尽管在这里,您可以通过以下方法使其更加清晰:
#!/bin/sh
i=1
while [ "$i" -ne 10 ]
do
echo "$i"
i=$((i + 1))
done
与中的一样init
,我们正在分配一个常量值,因此我们不需要评估算术表达式。该i != 10
中test
可以很容易地转换成一个[
表达式,并next
使用一个shell变量赋值,而不是一个变量赋值的算术表达式中,让我们摆脱:
和需要引用。
除了i++
-> 之外i = i + 1
,您可能还需要进行更多非POSIX的ksh / bash特定结构的翻译:
i=1, j=2
。该,
算术运算符是不是真正的 POSIX(以及在某些地区小数点分隔符与ksh93的冲突)。您可以像这样将其替换为另一个运算符+
,: "$(((i=1) + (j=2)))"
但使用起来i=1 j=2
会更加清晰。
a[0]=1
:POSIX shell中没有数组
i = 2**20
:POSIX Shell语法中没有幂运算符。<<
虽然支持,所以对于2的幂,可以使用i = 1 << 20
。对于其他权力,人们可以诉诸bc
:i=$(echo "3 ^ 20" | bc)
i = RANDOM % 3
:不是POSIX。POSIX工具箱中最接近的是i=$(awk 'BEGIN{srand(); print int(rand() * 3)}')
。