Linux에 표준 종료 상태 코드가 있습니까?


308

종료 상태가 0 인 경우 Linux에서 프로세스가 올바르게 완료된 것으로 간주됩니다.

분할 오류로 인해 종료 상태가 종종 11 인 것으로 나타났습니다. 단순히 이것이 작동하는 규칙 (모두 내부에있는 것처럼 실패한 앱) 또는 표준인지는 알 수 없습니다.

Linux에서 프로세스에 대한 표준 종료 코드가 있습니까?


6
시스템 기능에 의해 반환되는 "시스템 오류 번호"라는 것을 찾고 있다면 여기를보십시오. errno
marinara

답변:


86

리턴 코드의 8 비트와 킬 (killing) 신호 수의 8 비트는 wait(2)& co 의 리턴에서 단일 값으로 혼합됩니다 . .

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

int main() {
    int status;

    pid_t child = fork();
    if (child <= 0)
        exit(42);
    waitpid(child, &status, 0);
    if (WIFEXITED(status))
        printf("first child exited with %u\n", WEXITSTATUS(status));
    /* prints: "first child exited with 42" */

    child = fork();
    if (child <= 0)
        kill(getpid(), SIGSEGV);
    waitpid(child, &status, 0);
    if (WIFSIGNALED(status))
        printf("second child died with %u\n", WTERMSIG(status));
    /* prints: "second child died with 11" */
}

종료 상태를 어떻게 결정합니까? 일반적으로 쉘은 8 비트 리턴 코드 만 저장하지만 프로세스가 비정상적으로 종료 된 경우 상위 비트를 설정합니다.

$ sh -c 'exit 42'; 에코 $?
42
$ sh -c 'kill -SEGV $$'; 에코 $?
세그멘테이션 오류
139
$ expr 139-128
11

이 이외의 것을 본다면, 프로그램은 아마도 정상적으로 SIGSEGV호출 하는 시그널 핸들러를 가지고 exit있기 때문에 실제로 시그널에 의해 죽지 않을 것입니다. (프로그램 제외하고 어느 신호를 처리하도록 선택 가능 SIGKILL하고 SIGSTOP).


8
질문이 지금 나타나는 방식을 고려할 때, 이것은 가장 유용한 (그리고 받아 들여진) 대답으로 보이지 않습니다.
David J.

332

1 부 : 고급 Bash 스크립팅 안내서

항상 그렇듯이 Advanced Bash 스크립팅 안내서 에는 다음과 같은 유용한 정보 가 있습니다.

1 : 일반 오류에 대한 캐치
2 : 셸 내장의 오용 (Bash 문서에 따름)
126 : 호출 된 명령을 실행할 수 없음
127 : "명령을 찾을 수 없음"
128 : 종료 할 잘못된 인수
128 + n : 치명적 오류 신호 "n"
255 : 종료 상태가 범위를 벗어남 (종료시 0-255 범위의 정수 인수 만 취함)

제 2 부 : sysexits.h

ABSG 참조 sysexits.h.

Linux에서 :

$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h

/*
 * Copyright (c) 1987, 1993
 *  The Regents of the University of California.  All rights reserved.

 (A whole bunch of text left out.)

#define EX_OK           0       /* successful termination */
#define EX__BASE        64      /* base value for error messages */
#define EX_USAGE        64      /* command line usage error */
#define EX_DATAERR      65      /* data format error */
#define EX_NOINPUT      66      /* cannot open input */    
#define EX_NOUSER       67      /* addressee unknown */    
#define EX_NOHOST       68      /* host name unknown */
#define EX_UNAVAILABLE  69      /* service unavailable */
#define EX_SOFTWARE     70      /* internal software error */
#define EX_OSERR        71      /* system error (e.g., can't fork) */
#define EX_OSFILE       72      /* critical OS file missing */
#define EX_CANTCREAT    73      /* can't create (user) output file */
#define EX_IOERR        74      /* input/output error */
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
#define EX_PROTOCOL     76      /* remote error in protocol */
#define EX_NOPERM       77      /* permission denied */
#define EX_CONFIG       78      /* configuration error */

#define EX__MAX 78      /* maximum listed value */

5
어떤 종류의 유닉스에서는 일부 명령이 종료 상태 2를 사용하여 다른 것을 나타냅니다. 예를 들어, 많은 grep 구현에서는 종료 상태 2를 사용하여 오류를 표시하고 종료 상태 1을 사용하여 선택된 행을 찾을 수 없음을 의미합니다.
NamshubWriter

3
BSD에는 sysexits.h의 정보를 요약 한 매뉴얼 페이지가 있습니다 :man sysexits
georgebrock

6
@NamshubWriter가 말한 것. 종료 상태 2 는 "유닉스의 일부 특징"뿐만 아니라 일반적으로 유닉스 유틸리티에서 잘못된 명령 행 사용을위한 보편적 인 방법입니다. 이 답변에 표시된 머리글은 현재 또는 1987 년에 작성된 실제 규칙을 반영하지 않습니다.
alexis

ABS는 "위대한"것이 아닙니다. 주제를 읽으십시오. 비판을 찾는 것은 어렵지 않습니다.
tripleee

그러나 실제 공식 소스 코드는 sysexits.h어디에 있습니까? 모두가 참조 하는 매뉴얼 페이지 는 단지 산문입니다. 예를 들어 EX_OK다른 코드와 마찬가지로 실제로 참조 하지만 실제로 정의하지는 않습니다. 더없는 것이 있습니까?
Garret Wilson

71

'1' >>> 일반적인 오류에 대한 Catchall

'2' >>> 쉘 내장의 오용 (Bash 문서에 따름)

'126' >>> 호출 한 명령을 실행할 수 없습니다

'127' >>> "명령을 찾을 수 없음"

'128' >>> 잘못된 인수가 종료되었습니다

'128 + n' >>> 치명적 오류 신호 "n"

'130' >>> 스크립트가 Control-C에 의해 종료 됨

'255' >>> 종료 상태가 범위를 벗어남

이것은 bash 용입니다. 그러나 다른 응용 프로그램의 경우 다른 종료 코드가 있습니다.


1
같은 분에 둘 다 대답 한 것 같습니다. Tian은 귀하의 링크를보고 붙여 넣기에 매우 빠르지 않을 것입니다.
Nathan Fellman

6
'control-C yields 130'은 신호 n에 대해 '128 + n'과 일치합니다. control-C는 신호 2 인 SIGINT를 생성합니다.
Jonathan Leffler

3
이것은 속성없이 ABS에서 표절 된 것으로 보입니다. (우리는 ABS에 부정확하거나 오해의 소지가있는 정보를 포함하고 있기 때문에 알 수 있습니다.)
tripleee

4
고급 Bash 스크립팅 안내서 에 따라 예약 된 종료 코드 입니다. 따라서 사용자 지정 종료 매개 변수의 경우 이러한 값 을 피해야합니다 .
ingyhere

53

이전 답변 중 종료 상태 2를 올바르게 설명하는 것은 없습니다. 그들이 주장하는 것과는 달리 상태 2는 부적절하게 호출 될 때 명령 행 유틸리티가 실제로 리턴하는 것입니다. (예, 답은 9 살이 될 수 있으며, 수백 개의 공감대가 있으며 여전히 틀릴 수 있습니다.)

다음은 정상 종료를위한 실제적이고 장기적인 종료 상태 규칙입니다 (예 : 신호 별이 아님).

  • 종료 상태 0 : 성공
  • 종료 상태 1 : 프로그램에 의해 정의 된 "실패"
  • 종료 상태 2 : 명령 행 사용 오류

예를 들어 diff비교하는 파일이 동일한 경우 0을, 서로 다른 경우 1을 반환합니다. 오랜 관례에 따르면, unix 프로그램 은 잘못 호출 될 때 종료 상태 2를 리턴합니다 (알 수없는 옵션, 잘못된 수의 인수 등). 예를 들어 diff -N, grep -Y또는 diff a b c모두 $?2로 설정됩니다. 1970 년대 유닉스 초기.

허용 대답은 명령이 공급되었을 때 설명 신호에 의해 종료되었습니다. 간단히 말해서, 잡히지 않은 신호로 인해 종료되면 종료 상태가 128+[<signal number>됩니다. 예를 들어, SIGINT( 신호 2 )에 의한 종료는 종료 상태 130을 초래한다.

노트

  1. 몇 가지 답변은 종료 상태 2를 "bash 내장 오류 남용"으로 정의합니다. 이것은 bash (또는 bash 스크립트)가 상태 2로 종료 된 경우에만 적용됩니다 . 잘못된 사용 오류의 특수한 경우를 고려하십시오.

  2. 에서는 sysexits.h의에 언급 된 가장 인기있는 대답은 , 종료 상태 EX_USAGE없는 현실을 반영 ( "명령 줄 사용 오류")는 64로 정의하지만이 작업을 수행합니다 내가 인식하지 오전 어떤 잘못된 호출 수익률 64 (예 환영한다는 일반적인 유닉스 유틸리티 ). 소스 코드를 주의 깊게 읽으면 sysexits.h실제 사용법을 반영하기보다는 열망을 나타냅니다 .

     *    This include file attempts to categorize possible error
     *    exit statuses for system programs, notably delivermail
     *    and the Berkeley network.
    
     *    Error numbers begin at EX__BASE [64] to reduce the possibility of 
     *    clashing with oth­er exit statuses that random programs may 
     *    already return. 
    

    다시 말해, 이러한 정의는 당시의 일반적인 관행을 반영하지 않지만 (1993) 의도적으로 호환되지 않았습니다. 더 안타깝습니다.


어떻게해야이 프로그램 반환 하지 SIGINT / Ctrl-C를 잡기로 핸들 종료? 아직도 130? 배쉬 외에 다른 쉘을 사용하는 것이 중요합니까?
Gringo Suave

1
프로그램을 실행하는 쉘은 관련이 없습니다. 프로세스는 부모 프로세스에 따라 이론적으로 다른 상태로 종료하도록 선택할 수 있지만 이러한 상황이 발생하는 경우는 들어 본 적이 없습니다.
Alexis

1
프로그램이 SIGINT를 잡아서 정리하고 종료하는 경우 상태는 프로그램에 적합합니다. 예를 들어, more터미널 모드를 재설정하고 상태 0으로 종료합니다 (시도 가능).
Alexis

1
이 답변은 실제 경우보다 훨씬 높은 수준의 표준화를 의미합니다. 값 2의 의미에 대한 적절한 표준화가 없으며 실제 실무는 예측 가능하게 매우 혼합되어 있습니다. 많은 도구가 부적절한 사용법으로 2를 반환하는 것은 사실이지만 "부적절한 사용법"의 의미가 정확히 정의되어 있지는 않으며 다른 도구도이 규칙을 따르지 않습니다.
tripleee

@tripleee "도구"도 잘 정의되어 있지 않습니다! :-) 물론, 누구나 명령 줄 프로그램을 작성할 수 있으며, 무엇이든 반환 할 수 있지만 Linux보다 오래 된 GNU "유닉스 명령 줄 유틸리티"또는 GNU coreutils의 내용은 상당히 중요합니다. 이것에 일관성. 다르게 생각하면이 그룹에서 상태 2를 사용하지 않는 도구의 이름을 지정하십시오. 또한 "부적절한 사용"은 귀하의 용어입니다 (모호한 용어 임에 동의합니다). 나는 존재하지 않거나 호환되지 않는 옵션, 잘못된 수의 옵션이 아닌 인수 등과 같은 "명령 줄 사용 오류"를 작성했습니다.
Alexis

25

성공을 의미하는 0 외에 표준 종료 코드가 없습니다. 0이 아닌 것은 반드시 실패를 의미하지는 않습니다.

stdlib.h는 EXIT_FAILURE1과 EXIT_SUCCESS0 으로 정의 하지만 그 정도입니다.

11은 segfault의 경우 커널이 프로세스를 종료하는 데 사용하는 신호 번호이므로 segfault의 11은 흥미 롭습니다. 커널이나 셸에서 종료 코드로 변환하는 메커니즘이있을 수 있습니다.


20

sysexits.h 에는 표준 종료 코드 목록이 있습니다. 그것은 적어도 1993 년으로 거슬러 올라가고 Postfix와 같은 큰 프로젝트는 그것을 사용하므로 갈 길이라고 생각합니다.

OpenBSD 매뉴얼 페이지에서 :

style (9)에 따르면 프로그램을 종료 할 때 실패 조건을 나타 내기 위해 임의의 값으로 exit (3)을 호출하는 것은 좋지 않습니다. 대신 sysexits에서 사전 정의 된 종료 코드를 사용해야 프로세스의 호출자가 소스 코드를 찾지 않고도 실패 클래스에 대한 대략적인 추정을 얻을 수 있습니다.

8

첫 번째 근사값으로 0은 성공하고 0이 아닌 실패는 1이며 일반적인 실패는 1보다 크면 특정 실패입니다. 성공을 위해 1을 제공하도록 설계된 거짓 및 테스트의 사소한 예외 외에도 내가 발견 한 몇 가지 다른 예외가 있습니다.

보다 현실적으로 0은 성공 또는 실패를 의미하고 1은 일반적인 실패 또는 성공을 의미합니다. 2는 1과 0이 모두 성공에 사용되는 경우 일반적인 실패를 의미하지만 성공할 수도 있습니다.

diff 명령은 파일 비교가 동일하면 0을, 서로 다르면 1을, 이진이 다르면 2를 제공합니다. 2는 또한 실패를 의미합니다. less 명령은 인수를 제공하지 않으면 실패에 대해 1을 제공합니다.이 경우 실패에도 불구하고 0을 종료합니다.

실패가 권한 거부, 존재하지 않는 파일 또는 디렉토리 읽기 시도의 결과가 아닌 경우 more 명령 및 spell 명령은 실패에 대해 1을 제공합니다. 이러한 경우에는 실패하더라도 0을 종료합니다.

그런 다음 expr 명령은 출력이 빈 문자열이거나 0이 아닌 경우 성공에 1을 제공합니다.이 경우 0은 성공입니다. 2와 3은 실패입니다.

그런 다음 성공 또는 실패가 모호한 경우가 있습니다. grep이 패턴을 찾지 못하면 1을 종료하지만 실제 실패 (예 : 권한 거부)를 위해 2를 종료합니다. Klist는 티켓을 찾지 못하면 1을 종료합니다. 비록 grep이 패턴을 찾지 못하거나 빈 디렉토리 일 때보 다 더 이상 실패는 아닙니다.

불행히도 유닉스의 강력 함은 매우 일반적으로 사용되는 실행 파일에서도 논리적 규칙을 적용하지 않는 것 같습니다.


나는 diff의 행동도 지적하려고했다. wget에는 자세한 오류 (예 : 인증 실패의 경우 6)가 있지만 1 = 일반 오류, 2..n = 특정 오류
PypeBros

5

프로그램은 16 비트 종료 코드를 리턴합니다. 프로그램이 신호로 종료 된 경우 상위 바이트에는 사용 된 신호가 포함되고, 그렇지 않으면 하위 바이트는 프로그래머가 리턴 한 종료 상태입니다.

종료 코드가 상태 변수 $에 어떻게 할당됩니까? 그런 다음 쉘까지입니다. Bash는 상태의 하위 7 비트를 유지 한 다음 신호를 나타내는 데 128 + (신호 nr)를 사용합니다.

프로그램의 유일한 "표준"규칙은 성공의 경우 0, 오류의 경우 0이 아닙니다. 사용되는 또 다른 규칙은 오류시 errno를 반환하는 것입니다.


3

표준 Unix 종료 코드는 다른 포스터에서 언급했듯이 sysexits.h에 의해 정의됩니다. Poco와 같은 휴대용 라이브러리는 동일한 종료 코드를 사용합니다. 다음은 그 목록입니다.

http://pocoproject.org/docs/Poco.Util.Application.html#16218

신호 11은 SIGSEGV (세그먼트 위반) 신호이며 리턴 코드와 다릅니다. 이 신호는 잘못된 페이지 액세스에 대한 응답으로 커널에 의해 생성되어 프로그램이 종료됩니다. 신호 목록은 신호 매뉴얼 페이지에서 찾을 수 있습니다 ( "man signal"실행).


1

Linux가 0을 반환하면 성공을 의미합니다. 다른 것은 실패를 의미합니다. 각 프로그램에는 고유 한 종료 코드가 있으므로 모두 나열하는 데 시간이 오래 걸렸습니다 ...

11 오류 코드에 대해서는 실제로 세그먼테이션 오류 번호이며, 이는 대부분 프로그램이 할당되지 않은 메모리 위치에 액세스했음을 의미합니다.


1
커널은 커널을 죽이고 "종료 값"을 할당하기 때문에 항상 11입니다. 마찬가지로 다른 유형의 결함은 항상 동일한 종료 값을 갖습니다.
Alex Gartrell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.