development

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

big-blog 2020. 3. 17. 23:35
반응형

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 Scripting Guide 에는 훌륭한 정보가 있습니다 . (이것은 다른 답변에 있지만 비정규 URL에 연결되었습니다.)

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이 패턴을 찾지 못하거나 빈 디렉토리 일 때보 다 더 이상 실패하지는 않습니다.

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


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

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

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


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

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

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


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

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

참고 URL : https://stackoverflow.com/questions/1101957/are-there-any-standard-exit-status-codes-in-linux

반응형