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

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

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

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



답변

리턴 코드의 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).


답변

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 */


답변

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

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

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

‘127’ >>> “명령을 찾을 수 없음”

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

‘128 + n’ >>> 치명적 오류 신호 “n”

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

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

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


답변

이전 답변 중 종료 상태 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) 의도적으로 호환되지 않았습니다. 더 안타깝습니다.


답변

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

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

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


답변

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

OpenBSD 매뉴얼 페이지에서 :

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


답변

첫 번째 근사값으로 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이 패턴을 찾지 못하거나 빈 디렉토리 일 때보 다 더 이상 실패는 아닙니다.

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