배쉬 매뉴얼에서
실행된 명령의 종료 상태
waitpid
시스템 호출이나 동등한 함수에 의해 반환된 값입니다. 종료 상태의 범위는 0부터 255까지인데, 쉘에서는 아래 설명처럼 구체적으로 125보다 높은 값을 사용할 수도 있습니다. 쉘 내장 및 복합 명령의 종료 상태도 이 범위로 제한됩니다. 어떤 경우에는 쉘이 특정 오류 모드를 나타 내기 위해 특수 값을 사용합니다.
실행된 명령의 종료 상태를 결정하는 것은 무엇입니까?
- 명령 자체, 즉 명령의 구현이 종료 상태를 결정하는지 여부, 즉 명령 실행을 위한 명령줄 인수를 구문 분석하는 것이 명령에 내재된 것처럼 실행된 명령의 종료 상태를 결정하는 것이 명령의 고유 속성인지 여부
- 이 명령을 실행하는 쉘 프로세스는 무엇입니까? 위에서 언급한
시스템 호출waitpid
은 실행된 명령의 종료 상태가 쉘 프로세스에 의해 구현되고 명령 자체는 자체 실행의 종료 상태와 아무 관련이 없는 것으로 보입니다.
Bash 프로세스에서 실행된 명령의 종료 상태를 언제 얻을 수 있습니까?
- bash 프로세스가 대화형인 경우에만, 또는
- bash 프로세스가 대화형인지 비대화형인지에 관계없이? bash 프로세스가 비대화형일 때 bash 프로세스에서 실행된 명령의 종료 상태를 어떻게 검색합니까?
답변1
명령 자체는 exit()
시스템 호출에 대한 인수를 통해 종료 상태를 제공할 수 있습니다. 쉘(또는 다른 프로그램, Perl이나 PHP는 어떻습니까?)은 system()
또는 시스템 호출을 통해 하위 프로세스의 종료 상태를 얻을 수 있습니다. 자식 프로세스의 상태가 변경되면 Unix/Linux/*BSD 커널은 SIGCHLD를 부모 프로세스에 전달하도록 준비합니다.wait()
waitpid()
그러나 다른 상황도 있습니다. SIGKILL을 통해 종료된 프로세스는 종료될 기회가 없습니다. 잘못된 주소를 역참조하는 프로세스는 exit()
SIGSEGV 신호 처리기가 설치되어 있지 않으면 호출할 수 없습니다 . 이러한 경우 커널은 "신호에 의해 종료됨"을 나타내는 비트와 프로세스 종료를 유발한 신호를 포함하는 종료 상태를 계산합니다. 커널이 계산한 종료 상태는 종료된 프로세스의 상위 프로세스로 전달됩니다.
답변2
이 코드는 종료 상태를 설정합니다.
$ perl -e 'END { $? = 42 }'; echo $?
42
$
그렇지 않다면
$ perl -e 'sleep 999; END { $? = 42 }'
^C
$ echo $?
130
$ echo $((130-128))
2
$ kill -l | head -2
1 HUP Hangup 17 STOP Stopped (signal)
2 INT Interrupt 18 TSTP Stopped
$
아니면 실제로
$ perl -e '$SIG{INT}=sub{exit 7};sleep 999'
^C$ echo $?
7
$
아니면 누군가를 기분 좋게 만들어서는 안됩니다 SIGKILL
.
그렇지 않으면 bash
설명서가 waitpid
16비트 상태어를 설정했지만 bash
쉘 변수에 해당 상태어의 하위 집합만 전달하기 때문에 오해의 소지가 있습니다 $?
. 이는 쉘 사용자가 결과를 8비트 값(그렇지 않음)으로 처리하려고 시도하는 경우 waitpid
무지와 혼란을 초래할 수 있습니다 .
$ false; echo $?
1
$ perl -E 'system("false"); say $?'
256
$ perl -E 'system("false"); say $? >> 8'
1
$
답변3
프로세스는 자체 종료 코드를 결정합니다. 종료되면 종료 코드를 제공하고, 아무것도 제공되지 않은 경우 0(오류 없음)으로 가정합니다.
대화형 및 비대화형 쉘 모두에서 이전 명령의 종료 코드는 값을 통해 얻을 수 있습니다 $?
.