나는 for
에 참여하는 방법을 알고 있습니다 bash
.
POSIX 쉘 스크립트에서 동등한 루프를 수행하는 방법은 무엇입니까?
동일한 목표를 달성하는 방법은 여러 가지가 있으므로 자유롭게 답변을 추가하고 작동 방식을 자세히 설명하세요.
이러한 루프의 예는 bash
다음과 같습니다.
#!/bin/bash
for (( i=1; i != 10; i++ ))
do
echo "$i"
done
답변1
다음에서 유용한 정보를 찾았습니다.Shellcheck.net 위키, 나는 다음과 같이 인용합니다.
큰 타격 1:
for ((init; test; next)); do foo; done
POSIX:
: "$((init))" while [ "$((test))" -ne 0 ]; do foo; : "$((next))"; done
그러나 이는 POSIX가 아니므로 또는 i++
로 번역되어야 합니다 .i += 1
i = i + 1
:
항상 성공적인 종료 코드가 있는 빈 명령입니다. "$((expression))"
인수로 전달된 산술 확장입니다 :
. 산술 확장에서는 변수에 할당하거나 산술/비교를 수행할 수 있습니다.
따라서 문제의 위 스크립트는 다음 규칙을 사용하여 POSIX 방식으로 다시 작성할 수 있습니다.
#!/bin/sh
: "$((i=1))"
while [ "$((i != 10))" -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
상수값을 할당하므로 산술식을 평가할 필요가 없습니다. in은 쉽게 표현식으로 변환될 수 있으며, for는 산술 표현식 내에서 변수 할당 대신 쉘 변수 할당을 사용하므로 i != 10
인용할 필요가 없습니다.test
[
next
:
i++
-> 외에도 i = i + 1
ksh/bash 특정 구문의 POSIX 이외의 번역이 더 필요할 수도 있습니다.
i=1, j=2
.산술 연산자,
는진짜POSIX(일부 로케일에서는 ksh93의 소수 구분 기호와 충돌합니다.) 예를 들어 다른 연산자로 바꿀 수 있지만+
사용 하는 것이: "$(((i=1) + (j=2)))"
더i=1 j=2
명확합니다.a[0]=1
: POSIX 쉘에는 배열이 없습니다.i = 2**20
: POSIX 쉘 구문에는 지수 연산자가 없습니다.<<
그러나 2의 거듭제곱이 지원되므로i = 1 << 20
다른 거듭제곱의 경우 다음을 사용할 수 있습니다bc
.i=$(echo "3 ^ 20" | bc)
i = RANDOM % 3
: POSIX가 아닙니다. POSIX 도구 상자에서 가장 가까운 것은i=$(awk 'BEGIN{srand(); print int(rand() * 3)}')
.
1 기술적으로 이 구문은 ksh93 셸에서 왔으며 bash 외에도 zsh에서 사용할 수 있습니다.
답변2
위의 차이점에 대한 자세한 배경 정보를 제공해 주셔서 감사합니다. shellcheck.net을 사용할 때 나에게 도움이 된 대안은 다음과 같습니다.
세게 때리다
for i in {1..100}; do
...
done
POSIX
i=1; while [ $i -le 100 ]; do
...
i=$(( i + 1 ))
done
어떤 사람들은 seq도 seq 1 10을 사용하는 옵션이라고 지적했습니다. 루프를 생성하지만 seq가 있는 OS에 따라 다릅니다.
답변3
이 접근 방식은 $
임의의 변수를 삽입할 수 있으므로 더 일반적입니다.
#!/bin/sh
for i in $(seq 1 10); do
echo $i
done
유틸리티가 설치되어 있는지 확인하세요 . seq
하지만 .CoreUtils