La función system() en C++

Jinku Hu 12 octubre 2023
  1. Utilice la función system() en C++ para ejecutar el comando Shell
  2. Utilice system(nullptr) para comprobar si Shell está disponible en el sistema
  3. Utilice macros wstatus para comprobar el estado del comando ejecutado
La función system() en C++

Este artículo demostrará varios métodos para usar una función de biblioteca: system() en C++.

Utilice la función system() en C++ para ejecutar el comando Shell

La función system() ha sido parte de la biblioteca estándar de C durante un tiempo, y también se puede incluir en el código C++ sin bibliotecas adicionales. La función se utiliza para ejecutar un comando de shell desde el proceso de llamada. Sin embargo, tenga en cuenta que el system se crea para casos de uso especiales cuando el programa que realiza la llamada necesita generar un único proceso hijo e inmediatamente comenzar a esperar su terminación. Por lo tanto, la función en sí se implementa con múltiples llamadas al sistema que están disponibles como parte de la interfaz del sistema.

Si asumimos el entorno UNIX, el usuario no tiene que lidiar directamente con las funciones fork, exec y wait que controlan la creación / limpieza de un nuevo proceso. El siguiente ejemplo demuestra el caso de uso más simple para la función system, que ejecuta la utilidad de línea de comandos ls para imprimir los archivos en el directorio de trabajo actual.

#include <iostream>

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

  return EXIT_SUCCESS;
}

La función system() generalmente crea dos procesos para ejecutar un solo comando. Es decir, crea un shell con una llamada exec y otra para el comando dado que ejecutará el shell. Afecta negativamente el rendimiento en relación con el uso directo de las llamadas al sistema subyacentes. Observe que si ejecutamos el comando top con system, el programa está esperando hasta que el usuario salga de top manualmente, lo que volverá en el proceso de llamada y lo obligará a moverse a la instrucción return como se muestra en la siguiente ejemplo.

#include <iostream>

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

  return EXIT_SUCCESS;
}

Utilice system(nullptr) para comprobar si Shell está disponible en el sistema

La función system() toma una sola cadena de caracteres como argumento, que es el comando que debe ejecutarse desde el shell. Si le pasamos nullptr o NULL, se devuelve un valor distinto de cero cuando un programa de shell está disponible en el sistema, o si se devuelve el cero, indica que el shell no está disponible.

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

Producción :

shell is available on the system!

Utilice macros wstatus para comprobar el estado del comando ejecutado

Si la llamada al system no puede crear un proceso hijo, devuelve -1 y establece errno en consecuencia. Si la llamada a la función es exitosa, el valor de retorno es el código de estado de terminación del shell que ejecutó el comando dado. Además, este código de estado de terminación es el mismo que el código de salida del último comando que se ejecutó. Por lo tanto, uno puede examinar su valor usando las macros wstatus descritas en la llamada al sistema wait página de manual. El siguiente fragmento de código implementa una función printWaitStatus para verificar el valor de retorno del system e imprimir los detalles sobre el último comando que se ejecutó.

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

Producción :

(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