While 문: 여러 조건의 복합적인 작업을 수행할 수 없습니다.

While 문: 여러 조건의 복합적인 작업을 수행할 수 없습니다.

스키마 로 인수를 구문 분석하려고 합니다 recursive descent.

명령문 은 매 실행 후에 함수 while를 호출하여 eat!다음 처리를 가져옵니다 $current_token.

이제 문제는 이렇게 하면 무한 루프에 빠진다는 것입니다.

정확히 말하면 함수에는 두 개의 while 루프가 있습니다.

복합어가 구문상(또는 논리적으로?) 잘못되었기 때문에 둘 중 하나 또는 둘 다 작동하지 않습니다.

가능한 여러 수준에서 다음 코드에 어떤 문제가 있는지 확인해 주시겠습니까?

1)

while $(isWord? $current_token) || ! $(isVersionNumber? $current_token) && ! $(endOfInput?); do
while isVersionNumber? $current_token && ! endOfInput?; do

또한 무엇이 정답인가요? 명령 대체에 검사 기능을 넣을 것인가 말 것인가?

단락으로 인해 endOfInput?-test도 방지될 수 있습니까?

왜냐하면 루프가 완전히 중단되어야 하기 때문입니다.

일까츄님의 요청에 따라

테스트 기능의 코드:

isWord? () {
    local pattern="^[a-zA-Z0-9_-]+$"
    if [[ $1 =~ $pattern ]]; then
        echo true
    else
        echo false
    fi
}

isVersionNumber? () {
    local pattern="^[0-9]{1,2}(\.[0-9]{,2})*$"
    if [[ $1 =~ $pattern ]]; then
        echo true
    else
        echo false
    fi
}

EO_ARGS=1

function endOfInput? {
 if [ $current_token_index -ge $ARGC ]; then
    EO_ARGS=0
 fi
 echo $EO_ARGS
}

명령 대체에 사용하고 있기 때문에 다른 명령을 출력한다고 가정합니까?

아니요, 명령 대체 없이 조건부에서 함수를 호출할 수 있는지 여부를 모르기 때문에 시도했을 뿐입니다.

완전성을 위해 eat!기능도 추가합니다.

eat! () {
    
if [[ ! $(($current_char_index + 1)) -gt $ARGC ]]; then
  current_token=${ARGV[$current_token_index]}
  ((current_token_index += 1))

  current_char=${current_token:0:1}
}

그리고 조건이 test/ [( [[) 로 더 잘 공식화될 수 있을까요?

느낌표가 실패 지점이 될 수 있습니까?

다음은 구문상 잘못된 것 같습니다.

while [ endOfInput -eq 1 ] && isWord? "$current_token" || ! isVersionNumber? "$current_token"; do

괄호에서 [오류 메시지가 나타납니다.

[: endOfInput: integral expression expected (translation)

답변1

함수가 true에 대해 0을 반환하고 false에 대해 다른 것을 반환하는 경우 직접 사용할 수 있습니다.

my-true () {
    return 0
}

while my-true ; do
    echo Infinite loop...
done

false일 때 아무 것도 출력하지 않고 true일 때 무언가를 출력하는 경우 명령 대체를 사용하세요.

my-true () {
    echo OK
}
while [ "$(my-true)" ] ; do
    echo Infinite loop...
done

전자의 경우 함수를 연결하려면 &&||연산자를 사용할 수 있습니다.

while func1 && func2 ; do

후자의 경우 다음 대신 연결을 사용할 수 있습니다 ||.

while [ "$(func1 ; func2)" ] && [ "$(func3)" ]

후자의 경우 서브셸에서 호출되므로 함수의 전역 변수를 수정할 수 없습니다.

그런데 ?함수 이름에 사용하는 것은 금지되지 않지만 와일드카드이므로 문제가 발생할 수 있습니다.

abc? () {
    return $1
}
abc? 0   # Everything OK.
touch abcX
abc? 0   # line 9: ./abcX: Permission denied
abc\? 0  # This works, but where's the charm?

!기본 기록 확장 문자이지만 대부분 대화형 쉘에만 관련됩니다.

답변2

가능한 여러 수준에서 다음 코드에 어떤 문제가 있는지 확인해 주시겠습니까?

알았어 괜찮아.

또한 무엇이 정답인가요? 명령 대체에 검사 기능을 넣을 것인가 말 것인가?

명령 대체는 내부 명령이 무엇이든 가져옵니다.인쇄물, 명령줄에 입력합니다. (분할 및 글로빙 후 확장이 인용되지 않은 경우.) 따라서

foo() {
    echo true
}
if $(foo); then
    echo hello
fi

그러면 명령 대체가 생성되어 -statement true의 조건 부분에서 실행되고 if, 종료 상태를 사용하여 기본 분기가 if실행되는지 확인합니다. 이 경우에는 그럴 것입니다.

하지만 그건 어리석은 일이다. 명령 대체(Bash에서는 포크가 포함됨)를 거치지 않고 직접 종료 상태를 반환할 수 있습니다.

foo() {
    return 0
}
if foo; then
    echo hello
fi

true또는 마지막 명령의 종료 상태가 함수의 종료 상태로 사용되므로 로 함수를 종료할 수도 있습니다 .

따라서 다음과 같이 작성할 수 있습니다.

isWord? () {
    local pattern="^[a-zA-Z0-9_-]+$"
    if [[ $1 =~ $pattern ]]; then
        return 0
    else
        return 1
    fi
}
while isWord? "$current_token"

또는:

isWord? () {
    local pattern="^[a-zA-Z0-9_-]+$"
    [[ $1 =~ $pattern ]]
}
while isWord? "$current_token"

일반적인 이유(예: 단어 분할 및 글로빙)로 인해 변수를 인용해야 합니다.

while $(isWord? $current_token) || ! $(isVersionNumber? $current_token) && ! $(endOfInput?); do

여기서 a || b && c구성 그룹은 으로 그룹화됩니다 (a || b) && c. 즉, 왼쪽에서 오른쪽으로 실행됩니다. 실제 프로그래밍 언어와 달리그리고연산자보다 우선순위가 높습니다.또는(대신 그럴 것이라는 의미 a || (b && c)). 따라서 어떤 것이 필요한지 확인하십시오.

또한 Bash의 기본 설정에서는 다음과 같은 이름이 isWord?자주 문제가 되지는 않지만 여전히 glob입니다. 현재 디렉터리에 일치하는 파일이 있으면 해당 파일 이름으로 확장됩니다. failglob또는 사용으로 전환하면 nullglob해당 항목에도 영향을 미칩니다. 예를 들어 다음과 같습니다 failglob.

$ foo? () { echo hi; }
$ foo?
bash: no match: foo?
$ "foo?"
hi

글로브처럼 동작하지 않도록 하려면 이를 인용해야 합니다. Zsh에서는 기본적으로 일치하지 않는 glob이 실패합니다.

함수 이름의 마지막 문자인 bang은 중요하지 않습니다. 이름의 시작 부분이나 중간에 있고 쉘에 히스토리 확장이 켜져 있으면 히스토리 확장이 발생할 수 있습니다(대화식 쉘은 기본적으로 수행하지만 스크립트는 그렇지 않음).

단락으로 인해 endOfInput?-test도 방지될 수 있습니까?

와 같은 것이 있으면 while bar && ! endOfInput?; do그렇습니다. bar왼쪽에서 거짓 상태를 반환 하면그리고이미 알려져 있으므로 오른쪽은 건너뜁니다. 마찬가지로 ||진실한 반환도 마찬가지입니다. 그게 무슨 일 &&이야 ||.

하지만 이 질문에 대해 어떤 맥락도 제공하지 않았습니다. 즉, 함수가 호출되지 않는 경우 왜 중요한지 설명하지 않았으므로 이를 수행하는 더 나은 방법을 생각하기가 어렵습니다.

관련 정보