Bash에서 간단한 루프를 시도할 때 문제

Bash에서 간단한 루프를 시도할 때 문제
#!bin/sh
a=0
while["$a -lt 50"]
do
echo $a
a='expr $a+1'
done

나는 무한한 에코를 얻었다 expr $a+1. 내가 뭘 잘못했나요?

답변1

스크립트에 구문 오류가 있습니다. 다음을 사용하여 쉘 스크립트에 문제가 있는 구조가 있는지 확인할 수 있습니다.주택 검사온라인.

이것이 당신에게 말할 것입니다

Line 3:
while["$a -lt 50"]
^-- SC1009: The mentioned parser error was in this while loop.
     ^-- SC1035: You need a space after the [ and before the ].
     ^-- SC1069: You need a space before the [.
     ^-- SC1073: Couldn't parse this test expression.
                  ^-- SC1020: You need a space before the ].
                  ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.

변경으로 공간 문제 해결

while["$a -lt 50"]

입력하다

while [ "$a -lt 50" ]

대신 다음이 제공됩니다.

Line 3:
while [ "$a -lt 50" ]
           ^-- SC2157: Argument to implicit -n is always true due to literal strings.

Line 6:
a='expr $a+1'
  ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.

보고된 첫 번째 문제는 문자열에 관한 것입니다 "$a -lt 50". 사실, 여기서는 그런 문자열을 원하지 않습니다 "$a" -lt 50. 그런데 문자열은 항상 "true"이므로이것이 바로 루프가 무한한 이유입니다(구문 오류가 수정된 경우)

두 번째 문제는 검사기가 $a작은 따옴표로 묶인 문자열 내부의 변수를 감지하기 때문에 발생하는데, 이 변수는 해당 값으로 확장되지 않습니다(그렇기 때문에 인쇄된 문자열은 다음과 같습니다.expr $a+1). 해결책은 큰따옴표로 변경하지 않는 것입니다. 그러면 동일한 문자열이 제공되지만 값은 확장됩니다. 명령 을 실행하고 싶습니다 expr.

작은따옴표를 백틱으로 변경하면 됩니다.

이제 스크립트는 다음과 같습니다.

#!bin/sh
a=0
while [ "$a" -lt 50 ]
do
echo $a
a=`expr $a+1`
done

...그리고 ShellCheck는 여전히 만족스럽지 않습니다.

Line 6:
a=`expr $a+1`
  ^-- SC2006: Use $(..) instead of legacy `..`.
   ^-- SC2003: expr is antiquated. Consider rewriting this using $((..)), ${} or [[ ]].

$( ... )새로운 쉘 코드는 실제로 백틱 대신 백틱을 사용해야 합니다 . 또한 expr오래된 사용법에 대한 경고도 표시됩니다 .

이 줄은 다음과 같이 다시 작성할 수 있습니다.

a="$(( a + 1 ))"

최종 버전(들여쓰기 및 줄 수정 포함 #!):

#!/bin/sh

a=0
while [ "$a" -lt 50 ]; do
  echo $a
  a="$(( a + 1 ))"
done

bash또는 ksh93산술 평가용 버전을 사용하여 (( ... ))코드를 더욱 단축하세요.

#!/bin/bash

a=0
while (( a < 50 )); do
  echo "$(( a++ ))"
done

답변2

원본을 수정하세요

#!bin/sh
a=0
while [ "$a" -lt "50" ] # mind the spaces and double quote the variable
do
echo "$a"
a=`expr $a + 1` # replace single quotes with backticks, mind the space between $a and 1
done

개선하다

#!bin/bash  # Why not put bash here? sh may not always be linked to bash
a=0
while [ "$a" -lt "50" ] # mind the spaces and double quote the variable
do
echo "$a"
a=$(expr $a + 1) # replace legacy backticks with $()
# Or better you can even use double parenthesis which allows you do
# (( a++ )) , note the C style increment operator here
done

노트스크립트를 확인하려면 다음을 사용하십시오.[쉘 검사].

답변3

아니면 항상 for 루프를 사용하세요:

for ((a=0;a < 50; ++a))
do echo $a
done

빠르고 간단합니다. 실행하는 데 백틱이 필요하지 않습니다.

답변4

#!bin/sh
a=0
while [ $a -lt 50 ]
do
  echo $a
  a=$((a+1))
done

여기에는 모든 공간이 필요합니다.

관련 정보