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


10

명령을 고려하십시오

eval false || echo ok
echo also ok

일반적으로, 우리는 이것이 실행 기대 false유틸리티를하고, 종료 상태가 제로가 아닌 있기 때문에, 다음 실행 echo ok하고 echo also ok.

모두에서 POSIX 같은 내가 사용하는 쉘 ( ksh93, zsh, bash, dash, 오픈 BSD ksh, 그리고 yash)이 무슨 일이지만, 일이 우리가 사용하도록 설정하는 경우 흥미있어 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 okstring=false(가 종료 것) 오픈 BSD 쉘을 사용하고 나는 확실히 그것을 실수로 또는 오해, 또는 다른 무언가에 의해, 디자인되었다 아니었다.


eval false0이 아닌 상태를 생성하므로 set -e해당 시점에서 스크립트를 종료 할 것으로 예상 됩니다. ! set -eapply as not !statement 의 경우 종료 상태를 명시 적으로 확인합니다.
fcbsd

@fcbsd eval falseAND-OR 목록 또는 조건 문의 일부인 경우에도 스크립트를 종료 하시겠습니까 ? 나는하지 않을 것입니다.
Kusalananda

그것이 set -e올바른 행동인지 설정되어 있는지 확실하지 않습니다 ... 조건문으로 끝나지 않는 것이 합리적입니다.
fcbsd 2016 년

CentOS 7에서 sh를 사용하여 더 많이 연주했습니다 .OpenBSD의 ksh / sh를 사용할 때 의도 된 동작 set -e이므로`()`이 답입니다.
fcbsd 2016 년

답변:


4

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

있다는 것을 ||그것의 왼쪽에 하나의 리턴 코드에 의한 쉘 종료를 방지해야합니다 명령 줄에서.

특수 내장 오류로 인해 POSIX 에 따라 비 대화식 쉘이 종료 되지만 항상 그렇지는 않습니다. continue루프 를 벗어나 려고 하면 오류가 발생 continue하며 내장되어 있습니다. 그러나 대부분의 쉘은 다음과 같이 종료되지 않습니다.

continue 3

명확한 오류가 발생하지만 종료되지 않는 내장.

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

set -ePOSIX에서 종료 되는 정확한 조건 은 매우 모호합니다.


이것은 OpenBSD 메일 링리스트에서 나온 응답을 반영하지만 더 많은 단어로 감사합니다! 적절한 버그 보고서를 정리하고 아무 일도 일어나지 않으면 직접 소스 코드를 살펴 보겠습니다.
Kusalananda

4

[이것이 실제 답변이 아니라면 죄송합니다. 반올림하면 업데이트하겠습니다.]

소스 코드를 살펴본 결과는 다음과 같습니다.

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와 위 dash, zsh, yash, ksh93, 등

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.