• 이전 문서: [[/mac/terminal-guide/06]]

$? 으로 종료상태값 확인하기

지난 주에 rm -f를 설명할 때 $? 값을 출력해 보았습니다.

UNIX 시스템에서 모든 프로세스는 종료상태값을 갖습니다.

$?는 직전에 실행된 망령의 종료상태값을 담고 있는 특수한 변수입니다.

값의 범위는 다양하지만 가장 중요한 값은 0입니다. 이 글을 읽는 여러분은 초보자이니 대부분의 경우에는 0만 알아도 한동안은 충분할 수 있습니다.

  • 0: 에러 없음. 정상 종료.
  • 1 ~ 125: UNIX 시스템 정의 에러 코드.
  • 126: 실행 권한이 없음.
  • 127: 명령을 찾을 수 없음.
  • 130: control c로 종료됨.

정상적으로 실행되어 에러 없이 종료되면 0입니다. 저는 옛날에 이 값을 "에러 빵"으로 기억했습니다.

시간이 있다면 man errno를 입력해서 102까지의 값들에 대한 설명도 읽어보세요.

다음을 참고하는 것도 괜찮습니다.

0: Error 0

간단하게 [[/cmd/ls]]를 실행하고, 바로 뒤이어서 $?를 출력해 보겠습니다.

$ ls >/dev/null ; echo $?
0

0 이 나오는군요. 정상 종료된 모양입니다. ;는 명령어를 연결하는 구분자로 위의 명령은 사실 아래와 같은 것입니다.

$ ls >/dev/null

$ echo $?
0

그 외 몰라도 되는 것들?

rm으로 존재하지 않는 파일을 삭제하려 해보면 종료 상태가 1이 나옵니다.

$ rm qerqerqerqwerqer ; echo $?
rm: qerqerqerqwerqer: No such file or directory
1

ls로 없는 파일을 찾아보려 하면 2가 나옵니다.

$ ls aaasdf
gls: cannot access 'aaasdf': No such file or directory

$ echo $?
2

실행 권한이 없는 파일을 실행하면 126이 나옵니다.

$ touch a.txt

$ ./a.txt
-bash: ./a.txt: Permission denied

$ echo $?
126

존재하지 않는 명령을 실행하면 127이 나옵니다.

$ aaaasdfasdfa
-bash: aaaasdfasdfa: command not found

$ echo $?
127

실행중인 명령을 control c로 강제로 종료하면 130이 나옵니다.

$ yes >/dev/null
^C

$ echo $?
130

128 이후

128부터는 [[/study/os/signal]]{시그널}을 통해 프로세스가 종료될 때의 상태로 사용됩니다.

128에 시그널 번호를 더한 결과가 종료 상태가 된다고 생각하면 됩니다(128은 이진법으로 1000 0000이니까 간단해서 선택된 것 같습니다).

다음은 sleep 10 으로 10초간 대기를 시킨 다음, ctrl + c키를 입력해서 SIGINT(2)를 보낸 결과입니다.

$ sleep 10
^C

$ echo $?
130

128 + 2 = 130 이므로 종료 상태가 130이 됩니다.

각 [[/study/os/signal]]{시그널}의 번호가 궁금하다면 man signal을 입력하면 됩니다.

한편, C 프로그래밍 언어의 main 함수 시그니처를 기억하고 있다면 관례상 main 함수가 int를 리턴하도록 작성되곤 한다는 것을 알고 있을 것입니다.

이때 main 함수가 리턴하는 int가 바로 종료 상태값이 됩니다.

다음은 종료 상태로 0(성공, 에러 없음)을 리턴하는 경우입니다.

int main(int argc, char *argv[]) {
    return 0;
}

Java 또한 C 언어 계통의 언어이기 때문에 public static void main 역시도 C의 int main과 비슷한 모양을 갖습니다.

public static void main(String[] args){
  // 종료상태를 지정하지 않으면 0
}

Java로 작성한 애플리케이션에서 종료상태값을 수동으로 지정하려면 System.exit를 사용합니다.

System.exit(1);

System.exit의 JavaDoc을 읽어보면 비정상 종료인 경우 0이 아닌 값을 사용한다는 컨벤션도 명시하고 있습니다.

if 와 종료상태값

for 문의 사용

함수와 셸 스크립트