Linux에서 종료 코드의 최소값과 최대 값은 얼마입니까?


40

Linux에서 다음 종료 코드의 최소값과 최대 값은 얼마입니까?

  1. 이진 실행 파일 (예 : C 프로그램)에서 종료 코드가 반환되었습니다.
  2. 종료 코드는 bash 스크립트에서 호출했습니다 (호출시 exit).
  3. 종료 코드가 함수에서 호출되었습니다 (호출시 return). 나는이 사이라고 생각 0하고 255.

3 부에서 함수 에서 복귀한다는 의미 입니까? 즉, 쉘에 따라 달라질 수 있습니다,하지만 난 배쉬의 설명서를 말한다 "참고 종료 상태 사이에 떨어 0255 와" " 이 범위로 제한됩니다 쉘 내장 명령 및 복합 명령의 종료 상태. " return입니다, 물론, 쉘 내장합니다.
Toby Speight

관련 (대부분의 질문에 대한 답변이 있음) : 프로세스가 종료 될 때 기본 종료 코드가 있습니까?
Stéphane Chazelas

@TobySpeight, 그것은 bash쉘 의 한계입니다 . 와 같은 일부 다른 쉘은와 같은 zsh부호있는 32 비트 값을 반환 할 수 있습니다 exit. 일부는 지원하는 모든 유형 (스칼라 또는 목록)의 데이터를 좋아 rc하거나 es리턴 할 수 있습니다. 자세한 내용은 연결된 Q & A를 참조하십시오.
Stéphane Chazelas

답변:


73

_exit()/ exit_group()시스템 호출에 전달 된 번호 (종종 종료 상태 의 모호함을 피하기 위해 종료 코드 라고도 함) . 종료 코드 또는 신호 번호의 인코딩 및 프로세스가 종료 또는 정상적으로 종료되었는지에 따라 추가 정보를 나타냄 ) 유형은 Linux와 같은 Unix 계열 시스템에서 일반적으로 -2147483648 (-2 31 )에서 2147483647 (2 31 -1)의 값을 갖는 32 비트 정수입니다 .int

부모 프로세스 (또는 자식 subreaper 또는 그러나, 모든 시스템에서, init부모가 사망하는 경우)를 사용하여 wait(), waitpid(), wait3(), wait4()시스템 호출 만의 하위 8 비트가 0 ~ 255 (2 사용할 수 (값이며,이를 검색하는 8 - 1)).

waitid()API (또는 SIGCHLD의 신호 처리기)를 사용할 때 대부분의 시스템에서 (그리고 POSIX가 2016 년 표준 ( _exit()사양 참조 ) 에서 더 명확하게 요구됨에 따라 ) si_status반환 된 구조 의 필드 에서 전체 숫자를 사용할 수 있습니다. ). Linux에서는 아직 그렇지 않지만 waitid()API 를 사용하여 숫자를 8 비트로 자르지 만 앞으로 변경 될 가능성이 있습니다.

일반적으로 많은 쉘 $?종료 상태 표시 에서 128 이상의 값을 사용 하여 종료 되는 프로세스의 신호 번호를 인코딩하고 특수한 경우 126 및 127을 사용하므로 값 0 (일반적으로 성공을 의미 함)을 125로만 사용 하려고합니다. 정황.

126 ~ 255를 사용 exit()하여 쉘과 동일한 것을 의미 $?할 수 있습니다 (스크립트와 같은 경우 ret=$?; ...; exit "$ret"). 0-> 255 이외의 값을 사용하는 것은 일반적으로 유용하지 않습니다. 일반적으로 부모가 waitid()잘리지 않는 시스템 에서 부모가 API를 사용 하고 32 비트 범위의 값이 필요한 경우에만 그렇게 합니다. 당신이 할 경우주의 exit(2048)예를 들어, 즉 기존의 사용 부모에 의해 성공으로 간주됩니다 wait*()API를.

자세한 정보 :

Q & A는 다른 대부분의 질문에 희망적으로 답변하고 종료 상태의 의미를 명확히해야 합니다 . 몇 가지 더 추가하겠습니다 :

프로세스가 종료되거나 _exit()/ exit_group()시스템 호출을 호출하지 않으면 프로세스를 종료 할 수 없습니다 . 당신은에서 복귀 할 때 main()C반환 값으로, libc의 통화가 시스템 호출.

대부분의 언어에는 exit()시스템 호출을 래핑 하는 기능과 일반적으로 시스템 호출에 전달되는 값이있는 경우 사용하는 값이 있습니다. (일반적으로 exit()stdio 버퍼를 플러시하고 atexit()후크를 실행하는 C의 기능으로 수행되는 정리와 같은 더 많은 작업을 수행합니다 .)

적어도 그런 경우입니다.

$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234)                        = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234)                        = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234)                        = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)

0-255 이외의 값을 사용하면 불만을 나타내는 것을 가끔 볼 수 있습니다.

$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1)                           = ?

음수 값을 사용하면 일부 쉘이 불평합니다.

$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2)                           = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2)                           = ?

POSIX는 exit특수 내장으로 전달 된 값 이 0-> 255를 벗어나 면 동작을 정의되지 않은 상태로 둡니다 .

다음과 같은 경우 일부 셸에 예기치 않은 동작이 표시됩니다.

  • bash(그리고 기반이 mksh아닌 pdksh) 값을 8 비트로 자릅니다.

    $ strace -e exit_group bash -c 'exit 1234'
    exit_group(210)                         = ?
    

    따라서 해당 쉘에서 0-255 이외의 값으로 종료하려면 다음과 같이해야합니다.

    exec zsh -c 'exit -- -12345'
    exec perl -e 'exit(-12345)'
    

    즉 , 원하는 값으로 시스템 호출을 호출 할 수 있는 동일한 프로세스에서 다른 명령을 실행 합니다.

  • 다른 Q & A에서 언급했듯이 ksh93257에서 256 + max_signal_number의 종료 값에 대해 가장 이상한 행동을합니다 exit_group().

    $ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    zsh: suspended (signal)  ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    

    그렇지 않으면 bash/ 와 같은 숫자를 자릅니다 mksh.


¹ 다음 버전에서는 변경 될 수 있습니다. ksh93AT & T 이외의 지역 사회 노력으로 발전 이 이어 졌으므로 POSIX의 격려를 받아도 그 행동은 되돌려지고 있습니다.


2
si_statusLinux 에서 전체 종료 코드를 구현하는 것에 대한 토론이 있는지 알고 있습니까?
Ruslan

2
@Ruslan, 내가 준 링크에서 austingroupbugs.net/view.php?id=594#c1318 (Eric Blake (RedHat))
Stéphane Chazelas

1
"int 형식이므로 32 비트 정수입니다." 리눅스는 실제로 int가 항상 32 비트가 될 것이라고 보장합니까? 작은 마이크로 컨트롤러에서 실행할 때도? 그건 정말 이상해 POSIX는 그렇지 않습니다.
Voo

@Voo, 작은 마이크로 컨트롤러는 Linux를 실행할 수 없습니다. C는 int16 비트 이상이어야하지만 POSIX는 32 비트 이상이어야 하고 프로그래밍 환경에 uint32_t가 있어야합니다 . Linux가 int가 32 비트 이외의 프로그래밍 환경을 지원하는지 여부는 알 수 없습니다.
Stéphane Chazelas

1
POSIX 호환 OS에서는 최신 버전의 Bourne Shell에서 전체 32 비트 종료 코드를 얻을 수 있습니다. schillix.sourceforge.net/man/man1/bosh.1.html
schily

11

최소값은 0입니다. 성공 가치로 간주됩니다. 다른 모든 것은 실패입니다. 최대 값은 255이라고도합니다 -1.

이 규칙은 스크립트 및 기타 실행 파일과 쉘 기능 모두에 적용됩니다.

더 큰 값은 모듈로 256이됩니다.


2
정확히 말해, 일부 Bourne과 같은 쉘 (그러나 bash가장 일반적으로 사용되는 쉘 exit아님) 에서 내장 코드로 전달되는 종료 코드는 모듈로 -256으로 처리 되지 않고 대신 오류가 발생합니다. 예를 들어, 커먼 exit -1은 실제로 exit 255대부분의 셸에서 이식 가능한 것이 아닙니다 . 그리고 exit(-1)C 수준에서 동등한 지 여부 는 exit(255)사실상 확실하지만 세부적으로 구현 정의 동작에 의존합니다 (실제로 사용하는 현대 시스템에서는 문제가되지 않지만).
mtraceur

내가 아는 바로는 ksh93만이 exit(1)매개 변수를 8 비트로 제한합니다 .
schily

6

이건 너무 단순 해 보이지만

C 언어 (및 대부분의 다른 언어를 직간접 적 으로 따라 가기)는 반환 값과 동일한 인수를 사용하여 main호출 exit하는 것과 동일하게 반환해야합니다. 이 정수 (리턴 타입은 매우 명확입니다 int), 그래서 원칙적으로 범위가 될 것이다 INT_MININT_MAX.

그러나 POSIX는 전달 된 최하위 8 비트 만 exit문자 그대로 "status & 0xFF"인 것처럼 대기 부모 프로세스에서 사용할 수 있어야한다고 명시하고 있습니다 .
따라서 실제로 종료 코드는 가장 낮은 8 비트 만 설정되는 (서명 된) 정수입니다.

따라서 최소값은 -128이고 최대 값은 127 입니다. 잠깐만 요, 사실이 아닙니다. 0에서 255까지입니다.

그러나 아아, 물론 그렇게 간단 할 수는 없습니다 . 실제로 Linux (또는 bash) 는 다르게 작동합니다 . 리턴 코드의 유효 범위는 0-255입니다 (즉, 부호 없음).

혼동을 피하는 측면에서 안전을 유지하려면 리턴 코드가 서명되지 않았다고 가정 하고 다시 서명하지 않은 것을 캐스트하는 것이 좋습니다 wait. 그렇게하면 쉘에서 보는 것과 일치합니다. 최상위 비트 (가장 중요한 비트 포함)가 지워 지므로 기술적으로 부호가 있더라도 실제 값은 항상 부호가 없으므로 (부호 비트가 설정되지 않기 때문에) "잘못"되지 않습니다.
또한 종료 코드를와 비교하는 일반적인 오류를 피하는 데 도움이됩니다 -1. 이는 이상한 이유로 프로그램이 종료 될 때조차 나타나지 않는 것 같습니다 -1(왜, 왜!).

함수에서 돌아 오는 마지막 지점에 대해이 함수가 인 경우 main위를 참조하십시오. 그렇지 않으면 함수의 반환 유형이 무엇인지에 따라 원칙적으로 무엇이든 (를 포함하여 void) 될 수 있습니다 .


당신은 1989 년 전에 waitid()소개되었습니다.
schily

@schily : 무슨 뜻인지 잘 모르겠습니까? waitid()똑같은 일을 약간 다르게합니다. 그것은 특정 ID 또는 임의의 thread의 대기, 그리고 뾰족한-에에 결과를 기록 siginfo_t구조 si_status이다 int(그래서 ... 서명 , 그냥 같은). 그럼에도 불구 exit()하고 가장 낮은 8 비트 만 전달하므로 후드 아래에서 절대적으로 동일한 것입니다.
데이먼

exit()매개 변수의 모든 32 비트를 커널로 전달하고 waitid()종료 코드에서 32 비트를 모두 리턴합니다. 아무도 버그를 수정하지 않는 Linux를 확인했을 수 있습니다. 나를 믿지 않는다면 POSIX 호환 OS에서 확인하십시오.
schily

@schily : 그것이 사실이라면 (그렇지 않다고 생각하지만 어쨌든), Linux는 고장 났습니다 . "응답에 링크 된 POSIX 사양 exit, 특히"설명 "아래의 두 번째 줄 : "최소 8 비트 (즉, 상태 & 0377) 만 대기 상위 프로세스에 사용할 수 있지만) " . 이것이 32 비트가 아닌 최하위 8 비트를 따르는 구현 방식입니다. 32 비트에 대한 참조가 있습니까?
데이먼

나는 리눅스가 망가 졌다고 언급했다. 더 나쁜 것은 : 리눅스 커널 사람들은 버그 수정을 거부합니다. POSIX 표준을 읽으면 1995 버전 (SUSv1)이 1989 년에 SVr4에서 처음 도입 한 기능과 해당 표준의 최신 버전 (예 : SUSv7tc2)이 명시 적으로 설명되어 waitid()있고 siginfo_t구조체가 SIGCHLD처리기 리턴으로 전달 되었다는 사실을 정확하게 설명하고 있음 을 알 수 있습니다. exit()매개 변수 에서 모든 32 비트 .
schily

2
  1. 이진 실행 파일 (예 : C 프로그램)에서 종료 코드가 반환되었습니다.
  2. 종료 코드는 bash 스크립트에서 리턴되었습니다 (종료를 호출 할 때).

이진 실행 파일이든 셸 스크립트이든 다른 프로세스이든 관계없이 모든 프로세스의 종료 코드 범위는 0에서 255까지입니다. 더 큰 값을 전달할 수는 exit()있지만 하위 8 비트 만 사용할 수 있습니다. 를 통해 다른 프로세스 wait().

  1. 종료 코드는 함수에서 리턴되었습니다 (return 호출시). 나는 이것이 0과 255 사이라고 생각합니다.

AC 함수는 거의 모든 유형을 반환하는 것으로 선언 될 수 있습니다. 반환 값의 한계는 그 타입에 의해 전적으로 결정된다 : 예를 들어, -128 기능에 대한 (127)로 복귀 signed char하거나, 0 함수가 리턴하는 억 4.2 unsigned int, 또는 부동 소수점 숫자까지 포함 inf반환하는 함수 double. 처럼 그리고 즉, 숫자가 아닌 유형을 계산하지 않는 void *struct...

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