먼저 -1을 검사합니다
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
int status = system("exit 7");
if (status == -1) {
perror("system");
return 1;
}
if (WIFEXITED(status)) {
printf("exit=%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("signal=%d\n", WTERMSIG(status));
}
return 0;
}예제는 exit=7을 출력합니다. system의 반환값 자체는 7이라고 가정하지 않습니다. -1이면 자식 생성이나 상태 수집 같은 단계의 실패입니다. 그 외에는 wait 상태를 해석하는 매크로를 사용합니다. WEXITSTATUS는 WIFEXITED가 참일 때 읽습니다.
반환 상태는 명령 문자열을 실행한 셸의 상태입니다
- 호출한 프로그램명령 문자열을 system에 전달합니다.
- 셸의 명령 실행/bin/sh -c에 해당하는 의미로 문자열을 해석합니다.
- wait 상태 반환호출자는 정상 종료인지 시그널 종료인지 구분합니다.
번호는 처리 순서입니다. libc 구현이 내부에서 반드시 같은 fork 함수를 호출한다는 뜻은 아닙니다.
파이프라인이나 여러 명령을 넣으면 셸의 상태 규칙도 영향을 줍니다. 셸을 실행하지 못한 경우와 실제 명령이 127로 끝난 경우를 반환값만으로 항상 구분할 수는 없습니다. system(NULL)은 셸 사용 가능성을 묻는 별도 용법입니다.
명령 문자열이 필요하지 않다면 인자 배열을 사용합니다
문자열을 셸에 주면 공백, 따옴표, 치환, 리다이렉션도 문법으로 처리됩니다. 파일 이름이나 외부 입력을 붙여서 실행할 때 이 의미가 바뀔 수 있습니다. 셸 문법이 필요 없다면 exec 계열이나 posix_spawn으로 프로그램과 인자 배열을 분리하는 쪽이 명확합니다.
system 호출 중 SIGINT/SIGQUIT 처리는 보통 직접 실행한 프로그램과 다르게 보일 수 있습니다. 반복 호출하는 프로그램은 종료 요청을 무시한 채 반복하지 않도록 결과를 확인해야 합니다. 시그널 번호 비교를 할 때 WTERMSIG를 WIFSIGNALED 바깥에서 사용하지 않습니다.