BASH 스크립트의 무한 while 루프. BASH: for, while, Until 루프 설명 및 사용 예 예: 실행 파일 검색


저자 : 폴 코바우트
게시 날짜: 2014년 10월 16일
번역: A. 파닌
번역일자: 2014년 12월 21일

22장. 스크립트의 루프

테스트 명령

test 명령을 사용하면 표현식이 참인지 거짓인지 확인할 수 있습니다. 정수 값 10이 정수 값 55보다 큰지 테스트하는 것부터 시작해 보겠습니다. $ test 10 -gt 55 ; 에코 $? 1$

테스트 명령은 식이 false인 경우 1을 반환합니다. 그리고 다음 예에서 볼 수 있듯이 식이 true로 평가되면 test 명령은 0을 반환합니다. $ 테스트 56 -gt 55 ; 에코 $? $0

true 및 false 문자열로 작업하는 것이 더 편하다면 아래와 같이 test 명령을 사용할 수 있습니다. $ test 56 -gt 55 && echo true || echo false true $ test 6 -gt 55 && echo true || 에코 거짓 거짓

test 명령은 대괄호로 대체할 수도 있으므로 아래 예의 명령은 위 예의 명령과 정확히 동일합니다. $ [ 56 -gt 55 ] && echo true || echo false true $ [ 6 -gt 55 ] && echo true || 에코 거짓 거짓

다음은 일부 검사 구현의 예입니다. 개요는 man 테스트 페이지를 참조하세요. 추가 기능각종 점검 실시. [ -d foo ] foo 디렉토리가 존재합니까? [ -e bar ] bar 파일이 존재합니까? [ "/etc" = $PWD ] /etc는 $PWD 값과 동일합니까? [ $1 != "secret" ] 첫 번째 스크립트 매개변수의 값이 비밀 문자열과 다른가요? [ 55 -lt $bar ] 정수 값이 $bar 값보다 55 작습니까? [ $foo -ge 1000 ] $foo 값이 정수 값 1000보다 크거나 같습니까? ["알파벳"< $bar ] Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки? [ -f foo ] Является ли foo обычным файлом? [ -r bar ] Является ли bar 읽을 수 있는 파일? [ foo -nt bar ] foo는 bar보다 최신입니까? [ -o nounset ] nounset 쉘 옵션이 활성화되어 있습니까?

검사 연산자는 다음에 해당하는 연산자와 결합될 수 있습니다. 논리 연산"AND" 및 "OR". paul@RHEL4b:~$ [ 66 -gt 55 -a 66 -lt 500 ] && echo true || echo false true paul@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && echo true || echo false false paul@RHEL4b:~$ [ 66 -gt 55 -o 660 -lt 500 ] && echo true || 에코 거짓 참

조건부 점프 if then else

if then else 구문은 코드 옵션을 선택하기 위한 것입니다. 특정 조건이 true이면 일부 코드가 실행되고, 그렇지 않으면 다른 코드가 실행됩니다. 아래 예에서는 파일 존재 여부를 확인한 후 파일 존재 가정이 확인되면 해당 메시지를 표시합니다. #!/bin/bash if [ -f isit.txt ] 그러면 isit.txt 파일이 존재함을 에코합니다! 그렇지 않으면 에코 파일 isit.txt를 찾을 수 없습니다! fi

우리가 저장하는 경우 이 코드"choice"라는 파일에 스크립트를 추가하면 같은 방식으로 실행할 수 있습니다. $ ./choice 파일 isit.txt를 찾을 수 없습니다! $ touch isit.txt $ ./choice 파일 isit.txt가 존재합니다! $

조건부 점프 if then elif

게시할 수 있습니다. 새로운 운영자 elif 연산자를 사용하여 else 블록 내부에 있는 경우 조건부 점프. 다음은 그러한 항목의 간단한 예입니다. #!/bin/bash count=42 if [ $count -eq 42 ] then echo "42는 유효한 값입니다." elif [ $count -gt 42 ] then echo "너무 많습니다." 그렇지 않으면 "충분하지 않습니다."를 에코합니다. fi

for 루프

아래 예는 bash 셸의 클래식 for 루프 구문을 보여줍니다. for i in 1 2 4 do echo $i done

인라인 셸 호출과 결합된 for 루프를 사용하는 예입니다. #!/bin/ksh `seq 1 20`의 카운터에 대해 1부터 20까지 에코 계산을 수행하고 현재 값 $counter sleep 1 done

값 범위(값에서 값까지)에 대해 bash 쉘 선언을 사용하면 내장된 명령 쉘을 사용하지 않고도 위에 제시된 것과 완전히 유사한 스크립트를 생성할 수 있습니다. #!/bin/bash for counter in (1..20) do echo counting from 1 to 20, 현재 값 $counter sleep 1 done

이 for 루프는 패턴별로 파일을 검색하는 메커니즘을 사용합니다(명령 확장 메커니즘의 일부로 구현됨). 위의 지침이 직접 게시된 경우 명령줄, 유사하게 작동합니다. kahlan@solexp11$ ls count.ksh go.ksh *.ksh 파일의 경우 kahlan@solexp11$; cp $file $file.backup ; done kahlan@solexp11$ ls count.ksh count.ksh.backup go.ksh go.ksh.backup

while 루프

다음은 while 루프를 사용하는 간단한 예입니다. 나는=100; 동안 [ $i -ge 0 ] ; echo 100에서 0으로 카운트다운을 수행합니다. 현재 값은 $i입니다. 내가--; 완료

무한 루프는 while true 또는 while: 선언을 사용하여 구현할 수 있습니다. 여기서 기호:는 Korn 셸 및 bash에서 누락된 작업과 동일합니다. #!/bin/ksh # 무한 루프 while: do echo hello sleep 1 done

루프까지

아래는 Until 루프를 사용하는 간단한 예입니다. i=100이라고 하자; [ $i -le 0 ] 까지; echo 100에서 1로 카운트다운을 수행합니다. 현재 값은 $i입니다. 내가--; 완료

연습: 스크립트의 테스트 및 루프

3. while 루프를 사용하여 3부터 7까지 계산하는 스크립트를 개발합니다.

4. Until 루프를 사용하여 8에서 4까지 카운트다운하는 스크립트를 개발합니다.

5. 현재 디렉터리에서 확장자가 .txt인 파일 수를 계산하는 스크립트를 개발합니다.

6. 현재 디렉터리에 .txt 확장자를 가진 파일이 없는 경우 생성된 스크립트에서 if 문을 사용하여 올바르게 작동하도록 합니다.

실제 작업을 완료하기 위한 올바른 절차: 스크립트의 확인 및 루프

1. for 루프를 사용하여 3부터 7까지 계산하는 스크립트를 개발합니다.

#!/bin/bash for i in 3 4 5 6 7 do echo 3에서 7까지 계산, 현재 값 $i done

2. for 루프를 사용하여 1부터 17000까지 계산하는 스크립트를 개발합니다.

Bash 쉘은 일련의 값을 반복할 수 있는 for 루프를 지원합니다. 그게 바로 그거야 기본 구조그러한 주기:

목록의 var에 대해 do 명령 완료
루프가 반복될 때마다 변수 var는 다음 값에 기록됩니다. 목록. 따라서 루프의 첫 번째 패스에서는 목록의 첫 번째 값을 사용합니다. 두 번째 - 두 번째 등 - 루프가 마지막 요소에 도달할 때까지.

단순 값 반복

아마도 bash 스크립트에서 for 루프의 가장 간단한 예는 간단한 값 목록을 반복하는 것입니다.

#!/bin/bash for var in first second third third four five do echo $var 항목 완료
이 스크립트의 결과는 아래와 같습니다. $var 변수에 목록의 요소가 순차적으로 포함되어 있음을 분명히 알 수 있습니다. 이는 주기가 마지막에 도달할 때까지 발생합니다.


간단한 for 루프

$var 변수는 루프를 종료할 때 해당 값을 유지하고 해당 내용이 변경될 수 있으며 일반적으로 다른 변수와 마찬가지로 작업할 수 있습니다.

복잡한 값 반복

for 루프를 초기화하는 데 사용되는 목록에는 한 단어로 구성된 간단한 문자열뿐만 아니라 여러 단어와 구두점을 포함하는 전체 구도 포함될 수 있습니다. 예를 들어 다음과 같을 수 있습니다.

#!/bin/bash for var in first "두 번째" "세 번째" "하겠습니다" do echo "This is: $var" done
이 루프가 목록을 통과한 후에는 이런 일이 발생합니다. 보시다시피 결과는 꽤 예상됩니다.


복잡한 값 반복
TNW-CUS-FMP - 서비스 10% 할인을 위한 프로모션 코드, 7일 이내에 활성화 가능

명령 결과에서 얻은 목록으로 루프 초기화

for 루프를 초기화하는 또 다른 방법은 명령의 결과인 목록을 전달하는 것입니다. 여기서 명령 대체는 명령을 실행하고 작업 결과를 얻는 데 사용됩니다.

#!/bin/bash file="myfile" for var in $(cat $file) do echo " $var" done
이 예에서는 파일 내용을 읽는 cat 명령을 사용합니다. 결과 값 목록이 루프에 전달되어 화면에 표시됩니다. 우리가 접근하고 있는 파일에는 줄 바꿈으로 구분된 단어 목록이 포함되어 있으며 공백은 사용되지 않습니다.


파일의 내용을 반복하는 루프

여기서는 한 줄씩 데이터를 처리해야 하는 경우 해당 줄에 공백으로 구분된 여러 단어가 포함될 수 있는 더 복잡한 구조의 파일에서는 이러한 접근 방식이 작동하지 않는다는 점을 고려해야 합니다. 루프는 줄이 아닌 개별 단어를 처리합니다.

이것이 당신에게 전혀 필요한 것이 아니라면 어떨까요?

필드 구분 기호

위의 기능을 사용하는 이유는 다음과 같습니다. 환경 변수, IFS(내부 필드 구분자)라고 하며 필드 구분자를 지정할 수 있습니다. 기본적으로 bash 셸은 다음 문자를 필드 구분 기호로 간주합니다.
  • 공간
  • 탭 문자
  • 줄 바꿈 문자
bash는 데이터에서 이러한 문자 중 하나를 발견하면 해당 문자 앞에 목록의 다음 독립 값이 있다고 가정합니다.

문제를 해결하려면 IFS 환경 변수를 일시적으로 변경할 수 있습니다. 필드 구분 기호로 줄 바꿈만 필요하다고 가정하고 bash 스크립트에서 이를 수행하는 방법은 다음과 같습니다.

IFS=$"\n"
이 명령을 bash 스크립트에 추가하면 공백과 탭을 무시하고 개행 문자만 필드 구분 기호로 처리하여 예상대로 작동합니다.

#!/bin/bash file="/etc/passwd" IFS=$"\n" for var in $(cat $file) do echo " $var" done
이 스크립트가 실행되면 루프가 반복될 때마다 파일에 기록된 다음 줄에 대한 액세스를 제공하여 필요한 내용을 정확하게 출력합니다.


for 루프에서 파일을 한 줄씩 순회

구분 기호는 다른 문자일 수도 있습니다. 예를 들어 위에서는 /etc/passwd 파일의 내용을 표시했습니다. 행의 사용자 데이터는 콜론으로 구분됩니다. 루프에서 이러한 문자열을 처리해야 하는 경우 IFS를 다음과 같이 구성할 수 있습니다.

디렉토리에 포함된 파일 탐색

Bash 스크립트에서 for 루프의 가장 일반적인 용도 중 하나는 디렉터리에 있는 파일을 탐색하고 해당 파일을 처리하는 것입니다.

예를 들어 파일과 폴더를 나열하는 방법은 다음과 같습니다.

#!/bin/bash /home/likegeeks/*에 있는 파일에 대해 do if [ -d "$file" ] then echo "$file은 디렉토리입니다." elif [ -f "$file" ] then echo "$file은 디렉토리입니다. 파일" 완료됨
이 기사 시리즈의 이전 자료를 이해했다면 if-then 구문의 구조와 파일을 폴더와 구별하는 방법을 이해해야 합니다. 위 코드를 이해하기 어렵다면 이 자료를 다시 읽어보세요.

이것이 스크립트가 출력할 내용입니다.


폴더의 내용 표시

루프를 초기화하는 방법에 주의하세요. 와일드카드폴더 주소 끝에 "*"가 표시됩니다. 이 기호는 "모든 이름을 가진 모든 파일"을 의미하는 와일드카드로 간주될 수 있습니다. 그것은 당신이 정리할 수있게 해줍니다 자동 대체패턴과 일치하는 파일 이름.

if 문에서 조건을 테스트할 때 변수 이름을 따옴표로 묶습니다. 이는 파일이나 폴더 이름에 공백이 포함될 수 있기 때문에 수행됩니다.

C 스타일 for 루프

C 프로그래밍 언어에 익숙하다면 루프에 대한 bash를 설명하는 구문이 이상하게 보일 수 있습니다. 왜냐하면 분명히 다음과 같은 방식으로 루프를 설명하는 데 익숙하기 때문입니다.

(i = 0; 나는< 10; i++) { printf("number is %d\n", i); }
Bash 스크립트에서는 for 루프를 사용할 수 있습니다. 설명은 C 스타일 루프와 매우 유사하지만 몇 가지 차이점이 있습니다. 이 접근 방식을 사용한 사이클 다이어그램은 다음과 같습니다.

For ((변수 초기값; 루프 종료 조건; 변수 변경))
Bash에서는 다음과 같이 작성할 수 있습니다.

((a = 1;< 10; a++))
실제 예는 다음과 같습니다.

#!/bin/bash for ((i=1; i<= 10; i++)) do echo "number is $i" done
이 코드는 1부터 10까지의 숫자 목록을 출력합니다.

C 스타일의 루핑

while 루프

for 구조가 bash 스크립트에서 루프를 구성하는 유일한 방법은 아닙니다. 여기서 while 루프를 사용할 수도 있습니다. 이러한 루프에서는 특정 조건을 확인하고 테스트 중인 조건이 0을 반환할 때까지 루프 본문을 실행하거나 특정 작업이 성공적으로 완료되었음을 알리는 신호를 지정하는 명령을 지정할 수 있습니다. 루프 조건이 0이 아닌 값을 반환하면(오류를 의미) 루프가 중지됩니다.

다음은 while 루프의 구성 다이어그램입니다.
while 조건 확인 명령
하다
다른 팀
완료

다음과 같은 루프가 포함된 예제 스크립트를 살펴보겠습니다.

#!/bin/bash var1=5 while [ $var1 -gt 0 ] do echo $var1 var1=$[ $var1 - 1 ] 완료
루프 입구에서 $var1 변수가 0보다 큰지 확인합니다. 그렇다면 변수 값에서 하나를 빼는 루프의 본문이 실행됩니다. 이는 각 반복에서 발생하며 변수 값이 수정되기 전에 콘솔에 인쇄됩니다. $var1이 값 0에 도달하자마자 루프가 중지됩니다.

while 루프의 결과

$var1 변수를 수정하지 않으면 스크립트가 무한 루프에 빠지게 됩니다.

중첩 루프

다른 루프 실행을 포함하여 루프 본문에서 모든 명령을 사용할 수 있습니다. 이러한 구성을 중첩 루프라고 합니다.

#!/bin/bash for ((a = 1; a<= 3; a++)) do echo "Start $a:" for ((b = 1; b <= 3; b++)) do echo " Inner loop: $b" done done
아래는 이 스크립트가 출력할 내용입니다. 보시다시피, 먼저 외부 루프의 첫 번째 반복이 실행된 다음 내부 루프의 세 번의 반복이 실행되고, 완료 후 외부 루프가 다시 작동되고 내부 루프가 다시 실행됩니다.

중첩 루프

파일 내용 처리 중

대부분의 경우 중첩 루프는 파일을 처리하는 데 사용됩니다. 따라서 외부 루프는 파일의 줄을 반복하고 있으며 내부 루프는 이미 각 줄에서 작업하고 있습니다. 예를 들어, /etc/passwd 파일을 처리하는 방법은 다음과 같습니다.

#!/bin/bash IFS=$"\n" for $(cat /etc/passwd) do echo "$entry의 값 –" ​​IFS=: for value in $entry do echo " $value" done 완료
이 스크립트에는 두 개의 루프가 있습니다. 첫 번째는 개행 문자를 구분 기호로 사용하여 줄을 순회합니다. 내부는 필드가 콜론으로 구분된 문자열을 구문 분석하는 중입니다.

파일 데이터 처리

이 접근 방식은 필요에 따라 IFS 환경 변수에 구분 기호 문자를 작성하여 CSV 파일 또는 유사한 파일을 처리할 때 사용할 수 있습니다.

사이클 관리

아마도 루프에 들어간 후 루프 변수가 루프 종료를 위해 처음 지정된 조건과 일치하지 않는 특정 값에 도달하면 루프를 중지해야 할 것입니다. 이러한 상황에서 주기가 정상적으로 완료될 때까지 기다려야 합니까? 물론 그렇지 않습니다. 이러한 경우에는 다음 두 명령이 유용합니다.
  • 부서지다
  • 계속하다

중단 명령

이 명령을 사용하면 루프 실행을 중단할 수 있습니다. for 루프와 while 루프 모두에 사용할 수 있습니다.

#!/bin/bash for var1 in 1 2 3 4 5 6 7 8 9 10 do if [ $var1 -eq 5 ] then break fi echo "Number: $var1" done
정상적인 조건에서 이러한 루프는 목록의 전체 값 목록을 통과합니다. 그러나 우리의 경우 $var1 변수가 5와 같을 때 실행이 중단됩니다.

for 루프를 일찍 종료하기

여기에도 같은 내용이 있지만 while 루프에 대한 내용은 다음과 같습니다.

#!/bin/bash var1=1 while [ $var1 -lt 10 ] do if [ $var1 -eq 5 ] then break fi echo "Iteration: $var1" var1=$(($var1 + 1)) done
$var1이 5에 도달하면 실행되는 break 명령은 루프를 중단합니다. 콘솔에는 이전 예와 동일한 내용이 표시됩니다.

계속 명령

루프 본문에서 이 명령이 발견되면 루프를 종료하지 않고 현재 반복이 일찍 종료되고 다음 반복이 시작됩니다. for 루프의 continue 명령을 살펴보겠습니다.

#!/bin/bash for ((var1 = 1; var1< 15; var1++)) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done
루프 내부의 조건이 만족되면, 즉 $var1이 5보다 크고 10보다 작은 경우 쉘은 continue 명령을 실행합니다. 이로 인해 루프 본문의 나머지 명령을 건너뛰고 다음 반복으로 이동하게 됩니다.

for 루프의 continue 명령

루프에서 실행되는 출력 처리

루프의 데이터 출력은 출력을 리디렉션하거나 파이프라인에 전달하여 처리할 수 있습니다. 이는 done 문 뒤에 출력 처리 명령을 추가하여 수행됩니다.

예를 들어, 루프의 출력 내용을 화면에 표시하는 대신 파일에 모두 쓰거나 다른 곳에 전달할 수 있습니다.

#!/bin/bash for ((a = 1; a< 10; a++)) do echo "Number is $a" done >myfile.txt는 "완료되었습니다."라고 에코합니다.
쉘은 myfile.txt 파일을 생성하고 for 문의 출력을 해당 파일로 리디렉션합니다. 파일을 열고 우리가 기대하는 내용이 정확히 포함되어 있는지 확인해 보겠습니다.

루프 출력을 파일로 리디렉션

예: 실행 파일 검색

우리가 이미 다룬 내용을 활용하여 유용한 것을 작성해 봅시다. 예를 들어 시스템에서 사용할 수 있는 실행 파일을 찾아야 하는 경우 PATH 환경 변수에 기록된 모든 폴더를 검색할 수 있습니다. 우리는 이를 위해 필요한 모든 도구를 이미 보유하고 있으므로 모두 함께 사용하기만 하면 됩니다.

#!/bin/bash IFS=: for 폴더 in $PATH do echo "$folder:" for file in $folder/* do if [ -x $file ] then echo " $file" fi done done
작고 간단한 이 스크립트를 통해 PATH에서 폴더에 저장된 실행 파일 목록을 얻을 수 있었습니다.

PATH 변수에서 폴더의 실행 파일 검색

결과

오늘 우리는 bash 스크립트의 for 및 while 루프, 실행 방법 및 관리 방법에 대해 이야기했습니다. 이제 루프에서 다양한 구분 기호를 사용하여 문자열을 처리하는 방법, 루프의 데이터 출력을 파일로 리디렉션하는 방법, 디렉터리 내용을 보고 분석하는 방법을 알았습니다.

당신이 이 기사 시리즈의 첫 번째 부분과 두 번째 부분에 명시된 내용만 알고 있는 bash 스크립트의 개발자라고 가정하면 이미 유용한 것을 작성할 수 있습니다. 앞서 세 번째 부분은 매개변수와 명령줄 스위치를 bash 스크립트에 전달하는 방법과 이를 통해 수행할 작업을 배우게 될 내용을 이해한 후입니다.

루프 유형의 차이점에 대한 간략한 설명:

for - 실행할 객체가 있는 한 작업을 수행합니다(예: stdin, 파일 또는 함수에서 스트림 읽기).
while - 다음까지 작업을 수행합니다. 상태사실이다;
~까지 - 다음과 같은 기간 동안 실행됩니다. 상태사실이되지 않을 것입니다. 지금은 거짓입니다.

FOR 루프

루프가 포함된 이 버전의 스크립트를 고려해 보겠습니다.

$ cat loop.sh #!/bin/bash for 변수 `ls -1` do echo "$variable" done

구문은 매우 간단하며 예제에 매우 명확하게 표시되어 있습니다.

for(루프 시작) 변수(작업을 수행할 변수 선언) in(루프에 흐름 보내기) `ls -1`(실행되어 $variable 변수에 전달되는 명령). Do와 done은 수신된 데이터에 대해 주요 작업이 수행되는 루프의 "본문"이며, echo "$variable"은 루프에서 수행되는 실제 작업입니다.

이제 예제를 약간 변경하고 명령을 명시적으로 지정하는 대신 두 번째 변수를 사용하겠습니다.

$ cat loop.sh #!/bin/bash ls=`ls -1` for $ls do echo "$variable" done

이제 ls -1 명령이 별도의 변수로 전달되어 루프를 보다 유연하게 작업할 수 있습니다. 루프의 변수 대신 함수를 사용할 수도 있습니다.

$ cat loop.sh #!/bin/bash lsl () ( ls -1 ) for 변수 `lsl` do echo "$variable" done

for 루프의 주요 조건은 전달된 명령에 작업 개체가 포함되어 있는 한 실행된다는 것입니다. 위의 예를 기반으로 - ls -1에 표시할 파일이 있는 한 루프는 해당 파일을 변수에 전달하고 "루프 본문"을 실행합니다. 디렉터리의 파일 목록이 끝나자마자 루프 실행이 완료됩니다.

예제를 좀 더 복잡하게 만들어 보겠습니다.

디렉터리에는 다음과 같은 파일 목록이 포함되어 있습니다.

$ ls -1 파일1 파일2 파일3 파일4 파일5 loop.sh nofile1 nofile2 nofile3 nofile4 nofile5

그 중에서 "라는 단어가 없는 항목만 선택하면 됩니다. 아니요«:

$ cat loop.sh #!/bin/bash lsl=`ls -1` for $lsl do echo "$variable" | grep -v "no" done $ ./loop.sh file1 file2 file3 file4 file5 loop.sh

루프에서 조건식을 사용할 수도 있습니다( 조건식) […] 조건을 확인하고 조건이 트리거되면 루프를 중단하는 break 문을 사용합니다.

다음 예를 고려하십시오.

$ cat loop.sh #!/bin/bash lsl=`ls -1` for $lsl do if [ $variable != "loop.sh" ] then echo "$variable" | grep -v "no" else break fi 완료

루프는 loop.sh 파일이 발견될 때까지 계속됩니다. 루프 실행이 이 파일에 도달하자마자 루프는 break 명령에 의해 중단됩니다.

$ ./loop.sh 파일1 파일2 파일3 파일4 파일5

또 다른 예는 루프 본문을 실행하기 직전에 산술 연산을 사용하는 것입니다.

$ cat loop.sh #!/bin/bash for ((count=1; 개수<11; count++)) do echo "$count" done

여기서는 count=1, 제어 조건(count가 11보다 작은 경우), 실행할 명령(count +1) 등 세 가지 제어 명령을 설정합니다.

WHILE 및 UNTIL 루프

while 루프의 작동 방식을 명확하게 보여주는 간단한 예는 다음과 같습니다.

$ cat loop.sh #!/bin/bash count=0 while [ $count -lt 10 ] do ((count++)) echo $count done

$count 변수를 0으로 설정한 다음, "$count가 10보다 작으면 루프를 실행합니다."라는 조건으로 while 루프를 실행합니다. 우리가 실행하는 루프의 본문에서 접미사 증가$count 변수에 +1하고 결과가 stdout에 인쇄됩니다.

실행 결과:

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10

$count 변수의 값이 10이 되자마자 루프가 중지되었습니다.

while이 어떻게 작동하는지 보여주는 "무한" 루프의 좋은 예:

$ cat loop.sh #!/bin/bash count=10 while [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh ... 5378 5379 5380 5381 5382 5383 ^C

Until 루프는 유사하게 작동하지만 반대 방향으로 작동합니다.

$ cat loop.sh #!/bin/bash count=0 Until [ $count -gt 10 ] do ((count++)) echo $count done

여기서도 비슷한 조건을 설정했는데, '변수가 10보다 작은 동안'이 아니라 '변수가 10보다 커질 때까지'를 지정합니다. 실행 결과:

$ ./loop.sh 1 2 3 4 5 6 7 8 9 10 11

위의 "무한 루프" 예가 Until을 사용하여 실행되면 while과 달리 아무 것도 출력하지 않습니다.

$ cat loop.sh #!/bin/bash count=10 Until [ 1 = 1 ] do ((count++)) echo $count done $ ./loop.sh $

왜냐하면 " 상태"원래" 진실"—루프 본문은 실행되지 않습니다.

for 루프와 마찬가지로 while과 Until에서도 함수를 사용할 수 있습니다. 예를 들어, 서버 상태를 확인하는 실제 스크립트의 루프 수코양이(PID는 시스템에서 가져옵니다. SLES, 다른 시스템에서는 다를 수 있음), 약간 단순화된 버전입니다.

$ cat loop.sh #!/bin/bash check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) while check_tomcat_status do if [ -n "$ RUN" ] then printf "경고: Tomcat이 여전히 PID $RUN으로 실행 중입니다." else printf "Tomcat이 중지되었습니다. 진행 중...nn" break fi 완료

실행 결과:

$ ./loop.sh 경고: Tomcat은 여전히 ​​PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​​​PID 14435 26548로 실행 중입니다. PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​PID 14435 26548로 실행 중입니다.경고: Tomcat은 여전히 ​​PID 14435로 실행 중입니다.

풀 버전:

Check_tomcat_status () ( RUN=`ps aux | grep tomcat | grep -v grep | grep java | awk "(print $2)"` ) while check_tomcat_status; do if [ -n "$RUN" ] then printf "경고: Tomcat이 여전히 PID $RUN으로 실행 중입니다. 중지하시겠습니까? " 대답 "Tomcat 중지 중..." "설치 진행 중..." && $CATALINA_HOME/bin/shutdown .sh 2&>1 /dev/null || break sleep 2 if [ -n "$RUN" ] then printf "Tomcat이 아직 실행 중입니다. 종료하시겠습니까? " 대답 "Tomcat을 종료하는 중..." "설치 진행 중...n" && kill $RUN || break sleep 2 fi else printf "Tomcat이 중지되었습니다. 진행 중...nn" break fi done

답변 기능은 기사에 설명되어 있지만 여기서는 약간 개선된 버전이 사용됩니다.

답변 () (응답을 읽는 동안; |에서 echo case $response를 수행하십시오.) printf "$1n" return 0 break ;; |) printf "$2n" return 1 break ;; *) printf "Y(예) 또는 N(아니요)을 입력하세요! " esac done )

여기서는 while과 Until을 모두 사용할 수 있지만 for 루프는 사용할 수 없습니다. 왜냐하면 for는 한 번만 작동했기 때문입니다(PID를 수신하고 종료함).

루프는 프로그램이나 스크립트를 작성할 때 매우 편리하며 오히려 필요할 수도 있습니다. 이를 통해 특정 코드 섹션을 지정된 횟수만큼 실행할 수 있습니다. 당연히 bash에는 여러 유형의 루프가 있습니다. 주기를 설명하겠습니다. 동안, 동안, 동안, ~까지. for in과 for는 동일한 명령문의 서로 다른 구문으로 간주되지만 제 생각에는 while과 through보다 서로 더 다릅니다.

in에 대한 카운터가 있는 루프:

주기 안으로이것은 카운터가 있는 루프입니다. 루프 본문에 위치한 코드 블록은 for in 연산자 목록에 포함된 값의 개수만큼 반복되며, 각 반복마다 카운터 변수(여기서는 var라고 합니다. 물론 원하는 대로 부를 수 있습니다)에는 목록의 다음 요소 값이 있습니다.
do 키워드가 for 단어와 같은 줄에 있으면 인수 목록 뒤(do 앞)에 세미콜론을 입력해야 합니다.
각각의 요소<список>여러 인수가 포함될 수 있습니다. 이는 매개변수 그룹을 처리할 때 유용합니다. 이 경우 각 인수를 강제로 구문 분석하려면<списке>, set 명령어를 사용해야 합니다.
for 루프에서 변수를 목록으로 사용할 수 있습니다.
안에<списке>for 루프는 파일 이름을 사용할 수 있으며 파일 이름에는 와일드카드 문자가 포함될 수 있습니다. 이는 많은 수의 파일을 작업할 때 매우 유용할 수 있습니다.
만약에<список>for 루프에 지정되지 않은 경우 $@ 변수가 명령줄 인수 목록으로 사용됩니다.
인수 목록을 생성할 때 for 루프에서 명령 대체를 사용할 수 있습니다.
루프의 출력은 stdout에서 파일이나 다른 곳으로 리디렉션될 수 있습니다. 이에 대한 자세한 내용은 I/O 리디렉션을 참조하세요.

통사론:
var in의 경우<список>
하다
<выполняемые команды>
완료

예:
name1 name2 name3 name4의 이름에 대해
하다
$names를 에코합니다.
완료

루프 연산자 ~을 위한다른 작성 방법이 있습니다 - C 언어의 for 연산자 구문과 매우 유사합니다. 이 경우 카운터를 초기화할 때 변수 또는 하나의 변수의 초기 값이 설정되고 루프를 통과할 때마다 조건이 설정됩니다. 확인되고, 확인 결과가 true로 반환되면 루프의 다음 단계가 시작됩니다. 블록에서<приращение счётчиков>변수 카운터의 값은 조건을 확인할 때 조만간 false 값을 얻도록 반드시 변경되어야 합니다(반드시 위쪽으로 올라갈 필요는 없음). 그렇지 않으면 루프가 끝나지 않습니다. 지정된 횟수만큼 작업을 반복해야 하는 경우 매우 편리하고 가장 중요하게는 친숙한 옵션입니다.

비슷한 구문을 사용하면 다음과 같습니다.
을 위한 ((<инициализация счётчиков>; <проверка условия>; <приращение счётчиков>))
하다
<выполняемые команды>
완료

예:
for ((var=1; var<= LIMIT ; var++))
하다
에코 $var
완료

while 루프:

작업자 뒤의 상태를 확인하는 상당히 간단한 구성입니다. ~하는 동안이 조건이 true이면 do와 done 사이에 있는 명령 블록을 실행한 다음 다시 조건 확인을 진행합니다. 검사 결과가 false이면 주기가 종료되고 다음 명령이 실행되기 시작합니다. 완료. 다음을 보장하는 것이 필수적입니다.<проверка условия>루프에서 실행되는 코드에 따라 달라지며, 그렇지 않은 경우 검사 결과가 변경되지 않으면 무한 루프가 발생합니다.
while 루프의 표준 입력 장치는 리디렉션 명령을 사용하여 파일로 리디렉션될 수 있습니다.< в конце цикла.

통사론:
~하는 동안<Проверка условия>
하다
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
완료

예:
동안 [ $var0 -eq 100 ]
하다
에코 $var
var++
완료

운영자 ~하는 동안여러 가지 조건이 있을 수 있습니다. 그러나 그 중 마지막만이 주기를 계속할 가능성을 결정합니다. 이 경우 루프 연산자의 구문은 일반적인 연산자와 다릅니다.
통사론(마지막 조건만이 루프 실행에 영향을 미친다는 점을 다시 한 번 반복합니다) :
~하는 동안
<условие1>
<условие2>

<условиеN>
하다
<выполняемые команды - тело цикла>
완료

루프까지:

운영자 ~까지 while과 매우 유사하며 조건도 평가하지만 계산 결과가 false인 경우 루프 본문을 실행합니다. 이상해 보일 수도 있지만, while과 같이 루프의 첫 번째 전달 이전의 조건을 평가하며 이후가 아닌 조건을 평가합니다. for/in 루프와 마찬가지로 do 키워드를 루프 선언과 같은 줄에 배치할 때 ";" 문자를 삽입해야 합니다. 하기 전에.
이전 사례와 마찬가지로 조건은 루프 본문의 작업에 따라 달라져야 한다는 점을 기억하는 것이 중요합니다. 그렇지 않으면 스크립트가 완료되지 않습니다.

통사론:
~까지<Проверка условия>
하다
<Блок команд, обязательно меняющий переменные влияющие на проверку условия>
완료

예:
Until [ $var0 -gt 100] # 반복 시작 시 조건이 확인됩니다.
하다
에코 $var
var--
완료

지금은 아마도 충분할 것입니다. :)

  • 뒤쪽에
  • 앞으로

새 기사:

  • Windows 7/8/2008/2012에서 네트워크 검색이 켜지지 않습니다.
  • 오류: Qt 플랫폼 플러그인 "windows"를 찾거나 로드할 수 없기 때문에 이 애플리케이션을 시작하지 못했습니다.
  • 1C 8.3 서버에서 rphost.exe 작업자 프로세스의 자동 다시 시작 구성
  • MS SQL 2008/20012에서 트랜잭션 로그(.ldf)의 크기를 줄이는 방법

    괜찮은 산업용 DBMS와 마찬가지로 MS SQL은 데이터베이스와 함께 상태를 롤백할 수 있는 트랜잭션 로그를 유지합니다.

0 미란 발라-쿠마란

나는 왜 이 while 루프가 끝나지 않는지 이해하려고 노력하고 있습니다. 루프가 시작될 때 내 LOC 변수는 Testing/으로 설정됩니다. 이 디렉토리는 이 프로그램을 테스트하기 위해 만든 디렉토리이며 다음과 같은 레이아웃을 갖습니다.

모든 디렉토리에 "count" 기능이 적용되면 루프가 끝나기를 원합니다.
내가 시도한 것은 다음과 같습니다.

카운트 기능을 확인했는데 무한 루프가 생성되지 않습니다.

알고리즘을 수동으로 실행하려고 했습니다.

PARSE=1 LOC=$LOC/ count AVAILABLEDIR=$(ls $LOC -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") while [ $PARSE = "1" ] do if [[ $(AVAILABLEDIR[@]) == "" ]]; $(AVAILABLEDIR[@])에 대한 PARSE=0 fi DIRBASE=$LOC; $(LOCLIST[@])에서 LOC="$(DIRBASE)$(a)" LOCLIST="$LOCLIST $LOC" 카운트가 완료되었습니다. do TMPAVAILABLEDIR=$(ls $a -AFl | sed "1 d" | grep "/$" | awk "( print $9 )") PREPEND=$a if [[ $(TMPAVAILABLEDIR[@]) == "" ] ]; 그런 다음 $(TMPAVAILABLEDIR[@])에서 계속 fi를 수행합니다. TMPAVAILABLEDIR2="$TMPAVAILABLEDIR2 $(PREPEND[@])$(a)" 완료 NEWAVAILABLEDIR="$NEWAVAILABLEDIR $TMPAVAILABLEDIR2" 완료 AVAILABLEDIR=$NEWAVAILABLEDIR NEWAVAILABLEDIR="" LOC="" 완료

저는 정말 어려움을 겪고 있으며 어떤 의견이라도 주시면 감사하겠습니다. 지난 두 시간 동안 이 문제를 해결하려고 노력했습니다.

배쉬 무한 루프

답변 4개

-x 인수를 사용하여 스크립트를 실행하거나 첫 번째 줄에 작성해 보세요.

#!/bin/bash -x

그런 다음 그는 자신이 하는 모든 일을 당신에게 말해줍니다.

이 경우 두 가지 오류가 나타날 수 있습니다.

    TMPAVAILABLEDIR2를 다시 로드하지 않습니다.

    일반 파일에 대해서도 ls를 수행합니다.

정말로 재귀를 피해야 한다면, 재귀 없이 완전히 다음을 시도해 보세요.

#!/bin/bash count() ( echo counting "$1" ) todo=(테스트 중) while test $(#todo[@]) != 0 do doit=("$(todo[@])") todo= () for dir in "$(doit[@])" do for Entry in "$dir"/* # dir이 비어 있으면 "*"라는 항목이 표시됩니다 do test -e "$entry" || continue # 빈 디렉토리의 "*" 항목을 건너뜁니다. count "$entry" test -d "$entry" || 계속 할 일+=("$entry") 완료 완료 완료

그런데 왜 재귀를 사용할 수 없는지 알려주세요. 이것도 일종의 알레르기인가요? 맹세? 당신이 살고 있는 곳에 재귀적 소프트웨어를 금지하는 현지 법률이 있습니까?

모든 컷에 대해 "카운트"를 수행하고 싶다고 작성하셨습니다. 검색 옵션을 확인하세요.

$LOC 찾기 - 유형 d | 디렉토리를 읽는 동안; do cd $LOC cd $(dir) 계산 완료

또는 더 짧음(함수 카운터가 디렉터리를 매개변수 1로 사용하는 경우)

$LOC 찾기 - 유형 d | xargs 수

이제 find 또는 ls -R(재귀 함수)을 사용하고 싶지 않다는 것을 알았습니다. 그런 다음 다음과 같은 자신만의 재귀 함수를 만들어야 합니다.

함수 parseDir ( ls -d */ $1 | dir을 읽는 동안; parsDir $1/$dir done 계산)

이것이 효과가 있을지는 모르겠지만, 생각을 멈출 수 없는 흥미로운 질문입니다. 행운을 빌어요

사실이지만; "$(echo *)"의 단어에 대해 수행합니다. if [[ -d "$word" ]] ; then d[$((i++))]="$PWD"/"$word" elif [[ -f "$word" ]] ;then f[$((j++))]="$PWD"/"$ word" fi done [[ $k -gt $i ]] && cd .. cd "$d[$((k++))]" || 휴식 완료