Tôi đã tìm thấy thông tin hữu ích trong wiki Shellcheck.net , tôi trích dẫn:
Bash:
for ((init; test; next)); do foo; done
POSIX:
: "$((init))"
while [ "$((test))" -ne 0 ]; do foo; : "$((next))"; done
mặc dù hãy cẩn thận mà i++
không phải là POSIX vì vậy sẽ phải được dịch sang, ví dụ như i += 1
hoặc i = i + 1
.
Vì vậy, đoạn script trên trong câu hỏi có thể được viết lại POSIX-khôn ngoan bằng cách sử dụng các quy tắc như thế này:
#!/bin/sh
: "$((i=1))"
while [ "$((i != 0))" -ne 0 ]
do
echo "$i"
: "$((i = i + 1))"
done
Mặc dù ở đây, bạn có thể làm cho nó dễ đọc hơn với:
#!/bin/sh
i=1
while [ "$i" -ne 10 ]
do
echo "$i"
i=$((i + 1))
done
như trong init
, chúng ta đang gán một giá trị không đổi, vì vậy chúng ta không cần phải đánh giá biểu thức số học. Chữ i != 10
in test
có thể dễ dàng được dịch thành [
biểu thức và vì next
, sử dụng phép gán biến shell trái ngược với phép gán biến trong biểu thức số học, cho phép chúng ta thoát khỏi :
và cần trích dẫn.
Bên cạnh i++
-> i = i + 1
, có nhiều bản dịch hơn về các cấu trúc dành riêng cho ksh / bash không phải là POSIX mà bạn có thể phải thực hiện:
i=1, j=2
. Các ,
toán tử số học không phải là thực sự POSIX (và xung đột với các dấu phân cách thập phân ở một số vùng với ksh93). Bạn có thể thay thế nó bằng một toán tử khác +
như trong : "$(((i=1) + (j=2)))"
nhưng sử dụng i=1 j=2
sẽ dễ đọc hơn rất nhiều.
a[0]=1
: không có mảng nào trong vỏ POSIX
i = 2**20
: không có toán tử nguồn trong cú pháp shell POSIX. <<
được hỗ trợ mặc dù vậy đối với quyền hạn của hai, người ta có thể sử dụng i = 1 << 20
. Đối với các quyền hạn khác, người ta có thể dùng đến bc
:i=$(echo "3 ^ 20" | bc)
i = RANDOM % 3
: không phải POSIX. Gần nhất trong bộ công cụ POSIX là i=$(awk 'BEGIN{srand(); print int(rand() * 3)}')
.