La funzione system() in C++

Jinku Hu 12 ottobre 2023
  1. Usa la funzione system() in C++ per eseguire il comando della shell
  2. Usa system(nullptr) per verificare se Shell è disponibile sul sistema
  3. Usa le macro wstatus per controllare lo stato del comando eseguito
La funzione system() in C++

Questo articolo dimostrerà diversi metodi per utilizzare una funzione di libreria - system() in C++.

Usa la funzione system() in C++ per eseguire il comando della shell

La funzione system() fa parte da tempo della libreria standard C e può essere inclusa anche nel codice C++ senza librerie aggiuntive. La funzione viene utilizzata per eseguire un comando shell dal processo chiamante. Si noti, tuttavia, che system viene creato per casi d’uso speciali quando il programma chiamante deve generare un singolo processo figlio e iniziare immediatamente ad attendere la sua conclusione. Pertanto, la funzione stessa viene implementata con più chiamate di sistema disponibili come parte dell’interfaccia di sistema.

Se assumiamo l’ambiente UNIX, l’utente non deve occuparsi direttamente delle funzioni fork, exec e wait che controllano la creazione/pulizia di un nuovo processo. L’esempio seguente mostra il caso d’uso più semplice per la funzione system, che esegue l’utilità della riga di comando ls per stampare i file nella directory di lavoro corrente.

#include <iostream>

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

  return EXIT_SUCCESS;
}

La funzione system() di solito crea due processi per eseguire un singolo comando. Vale a dire, crea una shell con una chiamata exec e un’altra per il comando dato che la shell eseguirà. Influisce negativamente sulle prestazioni relative all’utilizzo diretto delle chiamate di sistema sottostanti. Si noti che se eseguiamo il comando top con system, il programma attende che l’utente esca da top manualmente, che tornerà nel processo di chiamata e lo costringerà a passare all’istruzione return come mostrato nella seguente esempio.

#include <iostream>

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

  return EXIT_SUCCESS;
}

Usa system(nullptr) per verificare se Shell è disponibile sul sistema

La funzione system() accetta una singola stringa di caratteri come argomento, che è il comando che deve essere eseguito dalla shell. Se gli passiamo nullptr o NULL, viene restituito un valore diverso da zero quando un programma di shell è disponibile sul sistema, oppure se viene restituito zero, indica che la shell non è disponibile.

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

Produzione:

shell is available on the system!

Usa le macro wstatus per controllare lo stato del comando eseguito

Se la chiamata system non riesce a creare un processo figlio, restituisce -1 e imposta errno di conseguenza. Se la chiamata alla funzione ha successo, il valore restituito è il codice di stato di terminazione della shell che ha eseguito il comando dato. Inoltre, questo codice di stato di terminazione è lo stesso del codice di uscita dell’ultimo comando eseguito. Quindi, si può esaminare il suo valore usando le macro wstatus descritte nella chiamata di sistema wait man page. Il prossimo frammento di codice implementa una funzione printWaitStatus per controllare il valore di ritorno system e stampare i dettagli sull’ultimo comando che è stato eseguito.

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

Produzione:

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