쉘 스크립트 종료 코드

쉘 스크립트 종료 코드

bash 종료 코드에 대해 질문이 있습니다. 기본적으로 내가 반환하는 각 코드의 의미를 정의할 수 있나요? 그렇다면 이를 정의하거나 문서화하는 표준 방법이 있습니까?

나는 그것을 조사한 결과 "공통" 종료 코드의 다양한 목록이 있다는 것을 발견했습니다. 예를 들어

또한 일부 GNU 문서를 살펴본 결과 약간 혼란스럽다는 것을 알았습니다.

종료 상태는 0에서 255 사이이지만 쉘은 아래 설명과 같이 구체적으로 125보다 높은 값을 사용할 수 있습니다.

어떤 종류의 표준 관행이 있는지 궁금합니다.

답변1

위 코드의 대부분은 쓰레기입니다. 이것은 공식적인 정의가 아닙니다. 난 다른 걸 찾았어고급 Bash 스크립팅 가이드

Exit Code Number
1   Catchall for general errors
2   Misuse of shell builtins (according to Bash documentation)
126 Command invoked cannot execute
127 "command not found"
128 Invalid argument to exit
128+n   Fatal error signal "n"
130 Script terminated by Control-C
255*    Exit status out of range

하지만 이 코드들은제안따라서 귀하의 목적에 맞게 자유롭게 사용하십시오.

답변2

이는 개별 비트 또는 비트 범위가 특정 의미를 갖는 status16비트 단어(JSON과 유사하지만 1970년대에는 특히 JSON과 같은 복잡한 작업 이후에는 16비트 레지스터가 흔하지 않은 상품이었습니다)입니다 . forkPerl은 호출에 의해 설정된 16비트 단어를 wait(2)변수에 넣고 $?상위 비트를 이동하여 특정 종료 코드를 찾을 수 있습니다. 왜냐하면 필드가 단어에 있는 위치이기 때문입니다.

$ perl -e 'fork || exit 42; wait; printf "%016b\n", $?'
0010101000000000
$ perl -e 'fork || exit 42; wait; printf "%016b\n", $? >> 8'
0000000000101010
$ perl -e 'fork || exit 42; wait; printf "%d\n", $? >> 8'
42

Unix 쉘은 status16비트 단어를 다른 형식으로 변환합니다.

$ perl -e 'exit 42'; echo $?
42

이는 코어 덤프(16비트 단어에 플래그가 있음) 또는 신호가 있는 경우 관련이 있습니다.

$ perl -MPOSIX -e 'raise SIGTERM'; echo $?
Terminated
143
$ echo $((143-128))
15
$ kill -l | grep 15
15   TERM Terminated                    31   USR2 User defined signal 2

따라서 이것은 신호 번호에 128을 더한 것이며(쉘은 이 값을 수정함) 실제 16비트 종료 상태 워드에서는 다음과 같이 나타납니다.

$ perl -MPOSIX -e 'fork || raise SIGTERM; wait; printf "%016b\n", $?'
0000000000001111
$ perl -E 'say 0b1111'
15

따라서 Perl은 호출에서 직접 반환된 16비트 단어를 사용 wait(2)하고 Unix 쉘은 이를 다른 형식으로 변환합니다. 사용하는 언어에 따라 C 규칙을 따르고 "종료 코드를 보려면 왼쪽으로 이동"과 같은 작업을 수행해야 합니다(일반적으로 이를 지원하는 매크로나 기타 호출이 있습니다. 자세한 내용은 설명서를 확인하세요). 또는 쉘 손상 값을 사용하는 경우 "128을 빼서 신호 번호를 찾으십시오".

추가 포인트를 얻으려면 코어 파일을 생성하는 프로그램을 만들고 종료 상태 단어가 어떻게 보이는지 확인하거나 다른 신호 번호 등을 시도하십시오.

상태어를 사용하는 방법

더 이상 사용되지 않을 수도 있고 그렇지 않을 수도 있는 다양한 규칙이 있습니다. 예를 들어 sysexits.h이러한 코드 중 일부는 이메일 전달 시스템에 중요하며(역사적으로 sendmail) 특정 코드를 사용하여 "재시도" 임시 실패를 나타낼 수 있습니다(in은 4xx가 됨). "거부하고 다시 시도" 대신에 SMTP의 코드). 이 이메일을 반송하세요'(5xx)를 선택하면 procmail메일 배달 에이전트 소프트웨어(또는 이와 유사한 소프트웨어)에서 이에 대한 참조를 볼 수 있습니다.

$ grep EX_TEMPFAIL /usr/include/sysexits.h
 *      EX_TEMPFAIL -- temporary failure, indicating something that
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */

그렇지 않으면 0일반적으로 "좋음"을 의미합니다(그러나 0이 아닌 코드를 설정하지 않으면 프로그램이 실패할 수 있으므로 구매자는 주의하십시오!). "아니요"는 0"나쁨"을 의미합니다(그러나 정확히 의미하는 바는 다릅니다. 일시적인 결함일 수도 있고, 소음이 무시될 수도 있고, 상황이 정말 안 좋을 수도 있습니다.) 특정 종료 코드는 사이트, 공급업체 또는 소프트웨어에 특정한 의미를 가질 수 있습니다. 이러한 특정 코드는 기록될 수도 있고 기록되지 않을 수도 있습니다. 페이지에는 다음과 같은 개요를 생성하는 man일반 매크로가 있는 경우가 많습니다 ..Ex -std

EXIT STATUS
     The foo utility exits 0 on success, and >0 if an error occurs.

또는 필요에 따라 보다 구체적인 문서를 제공하십시오(소프트웨어가 잘 문서화되어 있는 경우). 많은 소프트웨어가 제대로 문서화되어 있지 않습니다.

이것이 언제 중요합니까?

모니터 또는테스트 서버실제로 "0이 아닌 오래된 종료"와 segfault 또는 코어 덤프로 인해 갑자기 종료되는 프로그램을 구별해야 할 수도 있습니다. 또는 segfault가 특정 테스트에 대해 예상되는 값이고 그런 일이 발생하지 않는 경우는 일반적이지 않습니다. . 0만 보고하거나 0이 아닌 것으로 보고하는 모니터링이나 테스트는 귀중한 디버깅 정보를 무시합니다.

위에서 언급한 것처럼 SMTP 서버는 로컬 배달 에이전트가 반환한 정확한 종료 상태 단어에 따라 다양한 작업을 수행합니다. 하드 바운스는 서버가 다시 시도할 수 있는 일시적인 배달 실패와는 매우 다릅니다.

관련 정보