POSIX 쉘 스크립트에서 산술 루프를 만드는 방법은 무엇입니까?

POSIX 쉘 스크립트에서 산술 루프를 만드는 방법은 무엇입니까?

나는 for에 참여하는 방법을 알고 있습니다 bash.

POSIX 쉘 스크립트에서 동등한 루프를 수행하는 방법은 무엇입니까?

동일한 목표를 달성하는 방법은 여러 가지가 있으므로 자유롭게 답변을 추가하고 작동 방식을 자세히 설명하세요.

이러한 루프의 예는 bash다음과 같습니다.

#!/bin/bash
for (( i=1; i != 10; i++ ))
do
    echo "$i"
done

답변1

다음에서 유용한 정보를 찾았습니다.Shellcheck.net 위키, 나는 다음과 같이 인용합니다.

  1. 큰 타격 1:

     for ((init; test; next)); do foo; done
    
  2. POSIX:

     : "$((init))"
     while [ "$((test))" -ne 0 ]; do foo; : "$((next))"; done
    

그러나 이는 POSIX가 아니므로 또는 i++로 번역되어야 합니다 .i += 1i = 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 + 1ksh/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

관련 정보