쉘의 for 루프에서 제어 변수의 범위는 무엇입니까? [폐쇄]

쉘의 for 루프에서 제어 변수의 범위는 무엇입니까? [폐쇄]

쉘의 for 루프에 대해 질문이 있습니다.

다음과 같은 간단한 쉘 스크립트를 가정해 보겠습니다.

#!/bin/sh
loop() {                                                                                                                                                                                                                                                                                                               
    for i in 1 2 3 4; do                                                                                                                                           
        if [ $i -eq 2 ]; then                                                                                                                                      
            [ $1 -eq 2 ] && return 1                                                                                                                           
            loop $(($1 + 1)) && return 1                                                                                                                     
        fi                                                                                                                                                         
    done                                                                                                                                                           
return 1                                                                                                                                                       
}                                                                                                                                                                  

loop 0       

매개변수(및 함수 매개변수)를 제외한 모든 변수는 전역 변수입니다. 따라서 함수에 지역 변수가 필요하면 이를 매개변수로 전달해야 합니다.

이 간단한 스크립트를 실행해 보았지만 for 루프 목록(이 경우 1 2 3 4)도 로컬인지 확실하지 않습니다. 아래를 참조하세요:

+ loop 0
+ for i in 1 2 3 4
+ '[' 1 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 2 -eq 2 ']'
+ '[' 0 -eq 2 ']'
+ loop 1
+ for i in 1 2 3 4
+ '[' 1 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 2 -eq 2 ']'
+ '[' 1 -eq 2 ']'
+ loop 2
+ for i in 1 2 3 4
+ '[' 1 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 2 -eq 2 ']'
+ '[' 2 -eq 2 ']'
+ return 1
+ for i in 1 2 3 4
+ '[' 3 -eq 2 ']'
+ for i in 1 2 3 4
+ '[' 4 -eq 2 ']'   <- here is $i == 4
+ return 1
+ for i in 1 2 3 4
+ '[' 3 -eq 2 ']'   <- here is $i == 3, correctly behaving as local variable ...
+ for i in 1 2 3 4
+ '[' 4 -eq 2 ']'
+ return 1

for 루프가 내부적으로 어떻게 작동하는지 말해 줄 수 있는 사람이 있나요? for 루프 목록에 대해 약간 혼란스럽습니다. 이는 "로컬 변수"처럼 동작합니다.

모든 답변에 진심으로 감사드립니다! :)

답변1

$ reset() { i=$1; }
$ for i in 1 2 3 4 ; do echo -n "$i "; reset 3; echo "$i" ; done;
1 3
2 3
3 3
4 3

ilocal내부에서 이루어지지 않으므로 reset해당 변경 사항은 함수 외부에서 볼 수 있습니다. 그러나 변경 사항은 후속 반복에서 얻은 값에 영향을 미치지 않습니다 i. 명령 i에 나열된 단어는 for예상대로 한 번에 하나씩 순차적으로 할당됩니다.i

그렇습니다. 단어 목록의 위치를 ​​알려주는 "숨겨진 포인터"가 있습니다. 거기에 있어야 합니다. 그렇지 않으면 like와 같은 반복되는 단어가 포함된 루프가 for i in a a a ; do ...작동하지 않습니다. 반복할 때마다 i동일한 값을 얻지 만 루프는 여전히 고정된 반복 횟수만큼 실행됩니다.

답변2

당신이 무엇을 하고 싶은지 잘 모르겠지만,

  1. return 0당신은 함수에서 결코 ("true"), 그래서 그것은안 돼요모든 조합이 시도될 때까지 돌아갑니다.
  2. $i아니요지역 변수:

    $ foo() { i=1; bar; }
    $ bar() { echo $i; }
    $ foo
    1
    
  3. 각 명령이 어떤 줄에 있는지 확인하여 디버깅할 수 있습니다.

    trap 'printf "$LINENO "' DEBUG
    
  4. $1각각의 지역적이다함수 호출, 함수가 자신을 호출하더라도 계속되지 않습니다.

    $ foo() { if [ $# -ne 0 ]; then echo "One more time"; foo; fi; }
    $ foo 1
    One more time
    

    이는 모든 주요 고급 프로그래밍 언어에 해당됩니다. 그렇지 않으면 재귀가 완전히 깨집니다.

관련 정보