계속: "for", "while" 또는 "until" 루프에서만 의미가 있습니다.

계속: "for", "while" 또는 "until" 루프에서만 의미가 있습니다.

다음 반복으로 이동하기 위해 특정 기준(A)을 확인하는 루프가 있습니다. skip()라는 함수를 호출하면 continue루프(B)가 표시되지 않기 때문에 하위 프로세스에서 호출된 것처럼 나타난다는 것을 깨달았습니다. 또한 eval문자열에 의존하는 제안된 해결 방법은 작동하지 않습니다(C).

# /usr/bin/bash env

skip()
{
    echo "skipping : $1"
    continue   
}

skip_str="echo \"skipping : $var\"; continue"

while read -r var;
do
    if [[ $var =~  ^bar$  ]];
    then
        # A
        #        echo "skipping : $var"
        #        continue
        # B
        #        skip "$var" #  continue: only meaningful in a `for', `while', or `until' loop
        # C
        eval "$skip_str"
    fi
    echo "processed: $var"
done < <(cat << EOF 
foo
bar
qux
EOF
        )

방법 C:

$ source ./job-10.sh
processed: foo
skipping : 
processed: qux

또한보십시오:

Bash의 기능은 하위 프로세스로 실행됩니까?

PS1: 나중에 필요 < <하지 않고 이유를 알려줄 수 있는 사람이 있나요 ?<done

PS2: while따라서 태그를 찾을 수 없습니다.for

답변1

함수는 동일한 프로세스에서 실행되지만 루프와 구문이 다릅니다. 거의 모든 다른 프로그래밍 언어에서는 break함수 내부에서 또는 함수를 사용하여 외부 루프에 영향을 줄 수 없습니다 .continue

하지만 실제로 쉘에서는명시되지 않은:

continue [n]
만약에N지정되면 계속 유틸리티가 맨 위로 돌아가야 합니다.Nth에는 for, while 또는 Until 루프가 포함되어 있습니다. 만약에N지정되지 않음, 계속은 다음과 같이 동작합니다.N1로 지정됩니다. [...]

[...]둘러싸는 루프가 없으면 동작이 지정되지 않습니다.

얻는 내용은 셸에 따라 다릅니다.

Bash는 오류를 발생시키고 다음을 무시합니다 continue.

$ bash -c 'f() { continue; }; for x in a b c; do f; echo $x; done; echo done'
environment: line 0: continue: only meaningful in a ‘for’, ‘while’, or ‘until’ loop
a
environment: line 0: continue: only meaningful in a ‘for’, ‘while’, or ‘until’ loop
b
environment: line 0: continue: only meaningful in a ‘for’, ‘while’, or ‘until’ loop
c
done

Ksh는 이를 조용히 무시합니다.

$ ksh -c 'f() { continue; }; for x in a b c; do f; echo $x; done; echo done'
a
b
c
done

Dash, Yash 및 Zsh가 실제로 이를 적용하지만:

$ dash -c 'f() { continue; }; for x in a b c; do f; echo $x; done; echo done'
done

비슷한 고려 사항이 사용법에 적용될 수 있을 것으로 예상했지만 eval실제로는 그렇지 않은 것 같습니다. 적어도 나는 껍질 사이에 어떤 차이도 볼 수 없습니다.

대체로하지 마십시오. 그냥 적어보세요:

while read -r var;
do
    if [[ $var =~  ^bar$  ]];
    then
        echo "skipping '$var'"
        continue
    fi
    echo "processed: $var"
done

답변2

문제는 함수가 실행될 때 더 이상 루프 내부에 있지 않다는 것입니다. 서브셸에는 없지만 루프 내부에도 없습니다. 함수에 관한 한 이는 별도의 코드 조각이므로 어디서 호출되는지 알 수 없습니다.

그러면 실행하면 eval "$skip_str"정의되지 않은 시간에 $var설정했기 때문에 값이 없습니다. 이것은 실제로 예상한 대로 작동해야 합니다. 아무 이유 없이 매우 복잡하고 위험할 뿐입니다(입력을 100% 제어하지 않는 경우).skip_string$var

#! /usr/bin/env bash

while read -r var;
do
  skip_str="echo \"skipping : $var\"; continue"
  if [[ $var =~  ^bar$  ]];
  then
    eval "$skip_str"
  fi
  echo "processed: $var"

done < <(cat << EOF 
foo
bar
qux
EOF
        )

그거... 별로 안 예쁘네요. 개인적으로 저는 함수를 사용하여 테스트한 다음 테스트 결과에 대해 작업을 수행합니다. 이와 같이:

#! /usr/bin/env bash

doTest(){
  if [[ $1 =~  ^bar$  ]];
  then
    return 1
  else
    return 0
  fi
  
}

while read -r var;
do
  if doTest "$var"; then
    echo "processed: $var"
  else
    echo "skipped: $var"
    continue
  fi

## Rest of your code here

done < <(cat << EOF 
foo
bar
qux
EOF
        )

당신의 목표가 무엇인지 설명해 주시면 더 좋은 것을 드릴 수 있을 것 같습니다.

< <마지막으로, 이후에는 필요하지 done않습니다 < <(). 다음과 같은 <일반적인 입력 리디렉션 입니다 <().프로세스 교체이는 명령의 출력을 파일 이름으로 처리할 수 있는 트릭입니다.

그런 추가 작업을 반복하지 않기 위해 함수를 사용하는 경우 echo "skipping $1"함수에 더 많은 로직을 이동하여 루프가 있도록 하면 됩니다. 이 같은:협회

관련 정보