쉘 스크립트에서 while과 do 사이

쉘 스크립트에서 while과 do 사이

잘 작동하는 다음 스크립트가 있습니다.

!/bin/bash

a=12
while [ $a -gt 10 ]
do
    echo "$a"
    a=$(($a-1))
done
echo "done"

"do" 위에 "echo Something" 줄을 추가하면 해당 줄에 구문 오류가 나타날 것으로 예상됩니다. 우회하는 것 같아 [ $a -gt 10 ]무한루프가 됩니다. 어떻게 이런 일이 일어날 수 있습니까?

답변1

~에서배쉬 매뉴얼:

while

이 명령의 구문은 다음 while과 같습니다.

하지만테스트 명령;하다후속 명령;
완벽한
consequent-commands종료 상태가 0인 동안 test-commands 실행됩니다 . 반환 상태는 마지막으로 실행된 명령의 종료 상태 consequent-commands이거나 실행된 명령이 없으면 0입니다.

노트: test-commands,복수형. 테스트에서 여러 명령을 사용할 수 있으므로 다음은 명령 목록을 [ $a -gt 10 ]; echo "$a"테스트로 사용하는 완벽하게 유효한 루프입니다.

while [ $a -gt 10 ]
echo "$a"
do
   a=$(($a-1))
done

명령이 [ $a -gt 10 ]실패할 수도 있고 실패하지 않을 수도 있지만 echo(텍스트 쓰기에 실패하거나 다른 오류가 발생하지 않는 한) (거의) 항상 성공합니다.결정적인테스트 명령의 종료 상태는 항상 성공이며 루프는 항상 실행됩니다.

답변2

에서 man bash:

그리고 list-1; do list2; did while 명령은 다음과 같은 기간 동안
목록을 계속 실행합니다 .list-2
마지막 명령목록은 list-1
종료 상태 0을 반환합니다.

이는 a 가 list여러 명령을 포함할 수 있음을 의미하며, 이는 대부분 세미콜론이나 개행 문자로 구분됩니다.

따라서 이것은 완벽하게 작동합니다.

#!/bin/bash

a=12

while 
    echo something
    echo "a before test =  $a"
    [ a -gt 10 ]
do
    echo "a after test =  $a"
    a=$(($a-1))
done
echo "done"

is가 echo 이전의 마지막 명령인 경우 dodo가 수신한 종료 코드는 항상 true(0)이고 루프는 무한해집니다.

답변3

여기에 있는 다른 답변이 암시하지만 명시적으로 언급하지 않는 것은 이것이 [내장되어 있다는 것입니다.주문하다, 문의 문법 부분이 아닙니다 while.

help [명령줄에 다음을 입력 해 보세요 .

[: [arg... ]
조건식을 평가합니다.

이는 "test" 내장 함수의 동의어이지만 마지막 인수는 match 로 시작하는
리터럴 이어야 합니다 .][

그래서 당신의 스크립트는정확히처럼:

!/bin/bash
a=12
while test $a -gt 10
do
  echo "$a"
  a=$(($a-1))
done
echo "done"

다음으로 변경합니다:

!/bin/bash
a=12
while test $a -gt 10; echo something
do
  echo "$a"
  a=$(($a-1))
done
echo "done"

답변4

(다른 답변을 보완하기 위한 참고 사항)

조건 목록에서 여러 명령을 사용하는 것은 C와 유사한 루프를 구현하는 데 자주 사용됩니다 do { blah; blah; } while (condition). 여기서 조건은 루프의 끝에서 확인되어 루프의 코드가 한 번 이상 실행됩니다.

에서는 sh다음을 수행할 수 있습니다.

while
  blah
  blah
  condition
do
  continue # or :
done

다음과 같은 다른 방법도 가능합니다.

while true; do
  blah
  blah
  condition || break
done

또는:

continue=true
while "$continue"; do
  blah
  blah
  condition || continue=false
done
end=false
until "$end"; do
  blah
  blah
  condition || end=true
done

관련 정보