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 += 1hoặ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 != 10in testcó 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=2sẽ 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)}').