A função system() em C++

Jinku Hu 12 outubro 2023
  1. Use a função system() em C++ para executar o comando Shell de execução
  2. Use system(nullptr) para verificar se o Shell está disponível no sistema
  3. Use macros wstatus para verificar o status do comando executado
A função system() em C++

Este artigo demonstrará vários métodos de uso de uma função de biblioteca - system() em C++.

Use a função system() em C++ para executar o comando Shell de execução

A função system() faz parte da biblioteca padrão C há algum tempo e também pode ser incluída no código C++ sem bibliotecas extras. A função é usada para executar um comando shell do processo de chamada. Observe, porém, que system é criado para casos de uso especiais quando o programa de chamada precisa gerar um único processo filho e imediatamente começar a aguardar seu término. Portanto, a função em si é implementada com várias chamadas de sistema que estão disponíveis como parte da interface do sistema.

Se assumirmos o ambiente UNIX, o usuário não terá que lidar diretamente com as funções fork, exec e wait que controlam a criação / limpeza de um novo processo. O exemplo a seguir demonstra o caso de uso mais simples para a função system, que executa o utilitário de linha de comando ls para imprimir os arquivos no diretório de trabalho atual.

#include <iostream>

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

  return EXIT_SUCCESS;
}

A função system() geralmente cria dois processos para executar um único comando. Ou seja, ele cria um shell com uma chamada exec e outra para o comando fornecido que o shell executará. Afeta negativamente o desempenho em relação ao uso direto das chamadas de sistema subjacentes. Observe que se executarmos o comando top com system, o programa está esperando até que o usuário saia de top manualmente, o que retornará no processo de chamada e o forçará a mover para a instrução return conforme mostrado no seguinte exemplo.

#include <iostream>

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

  return EXIT_SUCCESS;
}

Use system(nullptr) para verificar se o Shell está disponível no sistema

A função system() aceita uma única cadeia de caracteres como argumento, que é o comando que precisa ser executado a partir do shell. Se passarmos nullptr ou NULL, um valor diferente de zero é retornado quando um programa de shell está disponível no sistema, ou se o zero é retornado, indica que o shell não está disponível.

#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;
}

Resultado:

shell is available on the system!

Use macros wstatus para verificar o status do comando executado

Se a chamada system falhar em criar um processo filho, ela retorna -1 e define errno de acordo. Se a chamada da função for bem-sucedida, o valor de retorno é o código de status de terminação do shell que executou o comando fornecido. Além disso, esse código de status de encerramento é igual ao código de saída do último comando executado. Assim, pode-se examinar seu valor usando as macros wstatus descritas na chamada do sistema wait página man. O próximo trecho de código implementa uma função printWaitStatus para verificar o valor de retorno do system e imprimir os detalhes sobre o último comando que foi executado.

#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;
}

Resultado:

(ls command output)
...
child exited, status=0
Autor: 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