`{{(exit 1); 1 번 출구; }; }`은 무슨 뜻인가요?


28

config.status의해 생성 된 다음 코드 스 니펫을 인용 했습니다 configure.

if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi

코드 스 니펫에서 무엇을 { (exit 1); exit 1; };합니까? exit서브 쉘 에서만하는 목적은 무엇입니까 ?

답변:


33

실행 (exit 1);ERR트랩 을 트리거하는 가장 간단한 방법입니다 . 또한 set -e유효한 경우 즉시 종료를 트리거합니다 . (오류 조건을 트리거하려면 명령이 실패해야합니다. exit서브 쉘에 실패 값이 있으면 서브 쉘이 실패합니다.)

exit 1; 그런 일을하지 않을 것입니다.

따라서 디버깅 목적으로 유용한 트랩 {(exit 1); exit 1;}을 먼저 생성 ERR한 다음 오류 표시와 함께 스크립트를 종료하는 데 사용할 수 있습니다 .

그러나 그것은 autoconf파일 에서 일어나고있는 것이 아닙니다 . autoconf스크립트 EXIT는 실행 중에 생성 된 임시 파일을 정리하기 위해 트랩에 의존 합니다. 를 포함한 대부분의 쉘 은 트랩을 호출하기 전에 명령에 bash제공된 값에서 상태를 설정합니다 . 이를 통해 트랩이 오류 또는 정상 종료에서 호출되었는지 여부를 감지 할 수 있으며 트랩 조작 종료시 종료 상태가 올바르게 설정되었는지 확인할 수 있습니다.exitEXITEXIT

그러나 분명히 일부 껍질은 협력하지 않습니다. autoconf설명서 의 인용문은 다음과 같습니다 .

로 생성 된 스크립트와 같은 일부 쉘 스크립트는 autoconf종료하기 전에 트랩을 사용하여 정리합니다. 마지막 쉘 명령이 0이 아닌 상태로 종료되면 트랩도 0이 아닌 상태로 종료되므로 호출자가 오류가 발생했음을 알 수 있습니다.

불행히도 Solaris와 같은 일부 셸에서 /bin/sh종료 트랩은 종료 명령의 인수를 무시합니다. 이러한 쉘에서 트랩은 일반 종료 또는 종료 1에 의해 호출되었는지 여부를 판별 할 수 없습니다. 종료를 직접 호출하는 대신 AC_MSG_ERROR이 문제점에 대한 임시 해결책이있는 매크로를 사용하십시오 .

해결 방법은 있는지 확인하는 것입니다 $?종료 상태가 되기 전에exit 때 확실히 그 값을가집니다 그래서, 명령이 실행 된 EXIT트랩이 실행됩니다. 그리고 실제로, AC_MSG_ERROR호기심 많은 코드를 삽입하고 중복 괄호로 완성하는 것이 매크로입니다.


false대신 대신 실행 하지 (exit 1)않습니까?
Ruslan

3
@Ruslan : 두 가지 문제. (1) 가장 중요 : false상태 코드를 설정할 수 없으며 0이 아닌 상태가 반환되는 것에 대해 보장하지 않습니다. (2) false일반적으로 내장되어 있지 않으므로 자식 프로세스가 필요합니다. 대조적으로, 대부분의 껍질은 처리 할 자식을 생성하는 것을 피할 수 있습니다 (exit 1).
rici

8

내가 볼 수있는 한 이것에 대한 목적은 없습니다. 서브 셸을 시작한 다음 즉시 종료하여 직접 얻을 수있는 것은 없습니다.

이와 같은 것은 코드 자동 생성의 부작용 일 가능성이 높습니다. 경우에 따라 서브 쉘에서 실행되는 다른 명령이있을 수도 있습니다 exit 1. 궁극적으로 생성 코드가 어떤 경우에는 기능이없는 일부 명령문을 삽입하고 매번 '클린 코드'를 생성하는 것이 더 복잡하여 어쨌든 단순화 될 가능성이 높습니다. 위의 코드 또는 위의 코드를 잘못 작성했습니다. :)

자유로이 사용하는 {...}것은 이것의 또 다른 예입니다. 대부분은 중복 적이지만 모든 경우에 코드를 삽입하는 코드를 작성하는 것이 더 쉽습니다. 필요하지 않은 것을 생략합니다.


목적이 있습니다. @rici의 답변을 참조하십시오.
Old Pro

1

(exit 1)특정 종료 코드를 얻는 가장 간단한 방법 일 것입니다 (1의 특별한 경우에는 더 쉬운 방법이 있습니다). 그러나 종료 코드를 검사하지 않기 때문에이 이유가 아닙니다.

exit서브 쉘 을 넣는 목적은 스크립트를 종료하지 않는 것일 수 있습니다 (특정 종료 코드 생성에 exit를 사용하더라도).

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