쉘 스크립트의 while 루프

쉘 스크립트의 while 루프

count 명령을 실행할 수 있지만 while 조건 내에서 사용하면 오류가 발생합니다.

-bash: [/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86-64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l: No such file or directory.


count="/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86- 
64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l"
while [ "$count" -ne 0 ]
do
echo "killing services and tomcat process"
/usr/bin/ps -aef|/usr/bin/egrep "catalina|java|wrapper-linux-x86- 
64"|/usr/bin/grep -v "catalina|java"|/usr/bin/awk '{print 
$2}'|/usr/bin/xargs kill -9
sleep 10
count="/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86- 
64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l"

done;

답변1

count="/usr/bin/ps -aef|...|wc -l"

변수에 명령을 저장하지 마십시오. 변수는 이를 위해 설계되지 않았으며 저장된 명령으로 작업하는 것은 어렵습니다. 명령을 어딘가에 저장하려면 다음 함수를 사용하십시오.

count_procs() {
    /usr/bin/ps -aef|...|wc -l
}

함수는 다른 명령처럼 사용할 수 있습니다.

표시되는 코드는 count해당 문자열의 값을 정수 0과 비교합니다. Bash는 [숫자가 아닌 값에 대해 불평합니다.

발생한 오류는 유사한 명령( ["$count" -eq 0 ]및 사이에 공백 없음)에서 발생할 수 있습니다. 이 경우 의 내용이 연결되어 실행될 명령의 이름인 명령줄의 첫 번째 단어를 형성하기 때문입니다. 그렇게 하는 것은 어리석은 일이지만 괄호, 파이프 문자 및 공백을 포함하는 경로를 갖는 것은 전적으로 가능합니다.[$countcount[

이제 실제로 명령을 실행하고 해당 출력을 캡처하여 0과 비교하려고 한다고 가정하면 명령 대체를 사용해야 합니다 $(...).

result=$(ps ... |wc -l)            # save the output of the command to `result`

또는

[ "$(ps ... | wc -l)" -eq 0 ] ... # use the command output directly in a test

루프가 실행될 때마다 프로세스 수를 계산하려면 루프 본문 내에서 명령을 실행해야 합니다. 예를 들어

while [ "$(ps ... | wc -l)" -eq 0 ]; do
    ...
done

또는 함수를 사용하세요.

count_procs() {
    /usr/bin/ps -aef|...|wc -l
}
while [ "$(count_procs)" -eq 0 ]; do
    ...
done  

루프 전에 프로세스를 한 번만 계산하면 조건이 일정해지며 루프는 무한정 반복되거나 전혀 반복되지 않습니다.

답변2

while 루프에서는 count 변수를 감소시켜야 합니다.

count=10
while [ $count -ne 0 ]; do
    echo "Count is $count"
    ((count--))
done

실제 산술을 수행하는 방법에는 다음과 같은 여러 가지가 있습니다.

  • ((count--))
  • ((count-=1))
  • ((count=count-1))
  • count=$((count - 1))

이중 괄호 구조에 대한 자세한 내용은 다음을 참조하세요.https://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/dblparens.html

다음을 사용할 수도 있습니다 let.

  • let "count--"
  • let "count-=1"
  • let "count=count-1"

자세한 내용은 다음을 let참조하세요.http://wiki.bash-hackers.org/commands/buildin/let


편집하다: 와 동일한 기능을 갖지 않는 POSIX 호환 셸에 대한 참고 사항입니다 bash.

Posix 쉘은 이 구문을 사용할 수 있습니다 $(( <expression> )). 따라서 위와 동일한 루프가 있고 kshCAE Issue 4(XPG4)와 같은 셸이나 공식 휴대용 셸에서 작동하는지 확인하려는 경우 sh:

  • count=$((count - 1))

이것이 중요한 경우 이 구문을 사용하면 bash 관련 구문을 사용하는 것보다 스크립트의 이식성이 더 높아집니다.

답변3

명령 대체 따옴표의 혼동 외에도 오류 메시지는 while ["$count" -ne 0]실제로 대괄호 주위에 필요한 공간이 없다는 것을 나타냅니다. 기억하세요. "while" 뒤의 부분은 실제로는주문하다, 그리고 루프가 끝나면주문하다0이 아닌 상태로 종료(참조https://www.gnu.org/software/bash/manual/bashref.html#Looping-Constructs).

누락된 공백으로 인해 bash는

while ["/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86-64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l" -ne 0]

실행하려고 합니다.주문하다 ["/usr/bin/ps -aef|...|wc -l"분명히 발견되지 않은 것 같습니다

이것이 [실제로는주문하다따라서 첫 번째 인수와 명령 이름을 구분하려면 명령 이름 뒤에 공백을 추가해야 합니다. (글을 쓰는 이유 ls -l와 쓰지 않는 이유는 같습니다 ls-l). 명령은 또한 [이것이 ]그의 것이어야 한다고 요구합니다.마지막따라서 매개변수 ]도 공백으로 구분해야 합니다.

Bash 프롬프트에서 help [help test(또한 help [[)를 입력합니다.

답변4

주요 문제는 다음과 같은 큰따옴표를 사용하는 것입니다.

$(...)

이 부분에 대해 몇 가지 의견이 있습니다(의견이 너무 깁니다).

while [ "$count" -ne 0 ]
do
echo "killing services and tomcat process"
done;

  • 루프에는 중지 메커니즘이 없습니다 while. 예를 들면 다음과 같습니다.

    count=$(( count - 1 ))
    
  • 스타일링 관점에서 보면~해야 한다내부 공간.

  • 끝에 세미콜론은 필요하지 않습니다.

관련 정보