Lin*_*eak 19 shell-script posix bourne-shell
我知道如何for在bash.
如何在 POSIX shell 脚本中执行等效循环?
由于有多种方法可以实现同一目标,请随意添加您自己的答案并详细说明其工作原理。
一个这样的bash循环的例子如下:
#!/bin/bash
for (( i=1; i != 10; i++ ))
do
echo "$i"
done
Run Code Online (Sandbox Code Playgroud)
Lin*_*eak 17
我在Shellcheck.net wiki 中找到了有用的信息,我引用:
重击:
for ((init; test; next)); do foo; done
Run Code Online (Sandbox Code Playgroud)
POSIX:
: "$((init))"
while [ "$((test))" -ne 0 ]; do foo; : "$((next))"; done
Run Code Online (Sandbox Code Playgroud)
但要注意这i++不是 POSIX,因此必须进行翻译,例如转换为i += 1或i = i + 1。
:是一个总是有成功退出代码的空命令。"$((expression))" 是一个算术展开式,作为参数传递给:. 您可以在算术扩展中分配给变量或进行算术/比较。
因此,问题中的上述脚本可以使用这些规则按 POSIX 方式重写,如下所示:
#!/bin/sh
: "$((i=1))"
while [ "$((i != 10))" -ne 0 ]
do
echo "$i"
: "$((i = i + 1))"
done
Run Code Online (Sandbox Code Playgroud)
虽然在这里,您可以通过以下方式使其更清晰:
#!/bin/sh
i=1
while [ "$i" -ne 10 ]
do
echo "$i"
i=$((i + 1))
done
Run Code Online (Sandbox Code Playgroud)
就像在 中一样init,我们分配了一个常量值,因此我们不需要计算算术表达式。该i != 10中test可以很容易地转换成一个[表达式,并next使用一个shell变量赋值,而不是一个变量赋值的算术表达式中,让我们摆脱:和需要引用。
除了i++-> 之外i = i + 1,还有更多非 POSIX 特定于 ksh/bash 的构造的翻译,您可能必须这样做:
i=1, j=2. 该,算术运算符是不是真正的POSIX(以及在某些地区小数点分隔符与ksh93的冲突)。您可以将其替换为其他运算符,如+in,: "$(((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)}').
感谢您对上述差异的深入背景知识。使用 shellcheck.net 时对我有用的替代品如下。
巴什
for i in {1..100}; do
...
done
Run Code Online (Sandbox Code Playgroud)
POSIX
i=1; while [ $i -le 100 ]; do
...
i=$(( i + 1 ))
done
Run Code Online (Sandbox Code Playgroud)
有些人指出 seq 也是使用 seq 1 10 的选项。创建一个循环,但这取决于 os 有 seq.