C++의 system() 함수

Jinku Hu 2023년10월12일
  1. C++의system()함수를 사용하여 셸 명령 실행
  2. system(nullptr)을 사용하여 시스템에서 셸을 사용할 수 있는지 확인
  3. wstatus매크로를 사용하여 실행 된 명령의 상태 확인
C++의 system() 함수

이 기사에서는 C++에서 라이브러리 함수 인system()을 사용하는 여러 방법을 보여줍니다.

C++의system()함수를 사용하여 셸 명령 실행

system()함수는 한동안 C 표준 라이브러리의 일부였으며 추가 라이브러리없이 C++ 코드에도 포함될 수 있습니다. 이 함수는 호출 프로세스에서 쉘 명령을 실행하는 데 사용됩니다. 그러나system은 호출 프로그램이 단일 하위 프로세스를 생성하고 즉시 종료 대기를 시작해야하는 특수한 사용 사례를 위해 생성됩니다. 따라서 함수 자체는 시스템 인터페이스의 일부로 사용할 수있는 여러 시스템 호출로 구현됩니다.

UNIX 환경을 가정하면 사용자는 새 프로세스 생성 / 정리를 제어하는fork,execwait기능을 직접 처리 할 필요가 없습니다. 다음 예제는ls명령 줄 유틸리티를 실행하여 현재 작업 디렉토리에있는 파일을 인쇄하는system함수의 가장 간단한 사용 사례를 보여줍니다.

#include <iostream>

int main() {
  system("ls");

  return EXIT_SUCCESS;
}

system()함수는 일반적으로 단일 명령을 실행하기 위해 두 개의 프로세스를 생성합니다. 즉, 하나의exec호출과 쉘이 실행할 주어진 명령에 대해 다른 하나의 쉘을 생성합니다. 기본 시스템 호출을 직접 사용하는 것에 비해 성능에 부정적인 영향을 미칩니다. system과 함께top명령을 실행하면 프로그램은 사용자가top을 수동으로 종료 할 때까지 대기합니다. 그러면 다음과 같이 호출 프로세스로 돌아가 강제로return문으로 이동합니다. 다음 예.

#include <iostream>

int main() {
  system("top");

  return EXIT_SUCCESS;
}

system(nullptr)을 사용하여 시스템에서 셸을 사용할 수 있는지 확인

system()함수는 쉘에서 실행해야하는 명령 인 단일 문자열을 인수로 사용합니다. nullptr또는NULL을 전달하면 시스템에서 쉘 프로그램을 사용할 수있을 때 0이 아닌 값이 리턴되고 0이 리턴되면 쉘을 사용할 수 없음을 나타냅니다.

#include <iostream>
#include <string>

using std::cout;
using std::endl;

int main() {
  auto ret = system(nullptr);
  if (ret != 0)
    cout << "shell is available on the system!" << endl;
  else
    cout << "shell is not available on the system!" << endl;

  return EXIT_SUCCESS;
}

출력:

shell is available on the system!

wstatus매크로를 사용하여 실행 된 명령의 상태 확인

system호출이 하위 프로세스 작성에 실패하면-1을 리턴하고 그에 따라errno를 설정합니다. 함수 호출이 성공하면 반환 값은 주어진 명령을 실행 한 쉘의 종료 상태 코드입니다. 또한이 종료 상태 코드는 마지막으로 실행 된 명령의 종료 코드와 동일합니다. 따라서wait시스템 호출 man page에 설명 된wstatus매크로를 사용하여 값을 검사 할 수 있습니다. 다음 코드 조각은printWaitStatus함수를 구현하여system반환 값을 확인하고 실행 된 마지막 명령에 대한 세부 정보를 인쇄합니다.

#include <cstring>
#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

void printWaitStatus(const char *msg, int status) {
  if (msg != nullptr) printf("%s", msg);

  if (WIFEXITED(status)) {
    printf("child exited, status=%d\n", WEXITSTATUS(status));
  } else if (WIFSIGNALED(status)) {
    printf("child killed by signal %d (%s)", WTERMSIG(status),
           strsignal(WTERMSIG(status)));
#ifdef WCOREDUMP
    if (WCOREDUMP(status)) printf(" (core dumped)");
#endif
    printf("\n");
  } else if (WIFSTOPPED(status)) {
    printf("child stopped by signal %d (%s)\n", WSTOPSIG(status),
           strsignal(WSTOPSIG(status)));
#ifdef WIFCONTINUED
  } else if (WIFCONTINUED(status)) {
    printf("child continued\n");
#endif
  } else {
    printf("status=%x\n", (unsigned int)status);
  }
}

int main() {
  auto ret = system("ls");

  if (ret == -1)
    cout << "a child process could not be created, or"
            "its status could not be retrieved!"
         << endl;
  else
    printWaitStatus(nullptr, ret);

  return EXIT_SUCCESS;
}

출력:

(ls command output)
...
child exited, status=0
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook