조건식의 "set -e"에서 "eval" 동작

조건식의 "set -e"에서 "eval" 동작

명령을 고려하십시오

eval false || echo ok
echo also ok

일반적으로 우리는 이것이 유틸리티를 실행 false하고 종료 상태가 0이 아니기 때문에 echo ok및 를 실행할 것으로 예상합니다 echo also ok.

내가 사용하는 모든 POSIX 계열 셸( ksh93, zsh, bash, dashOpenBSD kshyash)에서 이런 일이 발생하지만 를 활성화하면 상황이 흥미로워집니다 set -e.

set -e이 적용되면 OpenBSD 와 shksh(둘 다 에서 파생됨 pdksh)은 를 실행할 때 스크립트를 종료합니다 eval. 다른 어떤 쉘도 그렇게 하지 않습니다.

POSIX 라고특수 내장 유틸리티(예: eval)의 오류로 인해 비대화형 셸이 종료되어야 합니다. 실행이 "오류"를 구성하는지 완전히 확신할 수 없습니다 false(만일 오류가 있었다면 set -e활성 상태와 무관할 것입니다).

eval이 문제를 해결하는 방법은 하위 쉘에 넣는 것 같습니다 .

( eval false ) || echo ok
echo also ok

문제는 POSIX에 맞는 올바른 쉘 스크립트에서 이를 수행해야 하는지 아니면 OpenBSD 쉘의 버그인지 여부입니다. 또한 위에 링크된 POSIX 텍스트에서 "오류"는 무엇을 의미합니까?


추가 정보: OpenBSD 쉘은 명령을 echo ok사용하거나 사용하지 않고 모두 실행합니다.set -e

eval ! true || echo ok

내 원래 코드는 다음과 같습니다

set -e
if eval "$string"; then
    echo ok
else
    echo not ok
fi

어느 것이~ 아니다not okOpenBSD 쉘을 사용 하여 출력했는데 string=false(종료될 것임) 의도적으로, 실수로, 오해로 인해 발생한 것인지 확신할 수 없었습니다.

답변1

다른 쉘에는 그러한 해결 방법이 필요하지 않다는 것은 이것이 OpenBSD ksh의 버그라는 강력한 표시입니다. 실제로 ksh93에서는 이러한 문제가 나타나지 않습니다.

명령줄에 이 있다는 것은 ||그 왼쪽의 반환 코드 1로 인해 발생하는 쉘 종료를 피해야 합니다.

오류특별한내장으로 인해 비대화형 쉘이 종료됩니다.POSIX에 따르면그러나 그것은 항상 사실이 아닙니다. 루프를 벗어나 려고 시도하는 continue것은 오류이며 continue내장된 기능입니다. 그러나 대부분의 쉘은 다음에서 종료되지 않습니다.

continue 3

명확한 오류를 발생시키지만 종료되지는 않는 내장 기능입니다.

따라서 종료는 명령의 내장 특성이 아닌 조건 false에 의해 생성됩니다 ( 이 경우).set -eeval

종료되어야 하는 정확한 조건은 set -ePOSIX에서 훨씬 더 모호합니다.

답변2

[실제 답변이 아닌 경우 죄송합니다. 답변이 완료되면 업데이트하겠습니다.]

소스코드를 보고 내린 결론은 이렇습니다.

1) 버그/제한 사항이며 그 뒤에 철학적인 내용은 없습니다.

2) OpenBSD ksh( mksh)의 휴대용 포크에서 이에 대한 "수정"은 다음과 같습니다.매우가난하고, 실제로 고치지는 못한 채 상황을 더욱 악화시키기만 합니다.

다른 모든 쉘과 다른 새로운 버그:

mksh -ec 'eval "false; echo yup"'
yup

bash -ec 'eval "false; echo yup"'
(nothing)

아직 해결되지 않았습니다.

mksh -ec 'eval "set -e; false" || echo yup'
(nothing)

bash -ec 'eval "set -e; false" || echo yup'
yup

위의 내용을 , , , 등 bash으로 바꿀 수 있습니다 .dashzshyashksh93

관련 정보