Die system()-Funktion in C++

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie die Funktion system() in C++, um Shell-Befehle auszuführen
  2. Verwenden Sie system(nullptr), um zu überprüfen, ob Shell auf dem System verfügbar ist
  3. Verwenden Sie wstatus-Makros, um den Status des ausgeführten Befehls zu überprüfen
Die system()-Funktion in C++

Dieser Artikel demonstriert mehrere Methoden zur Verwendung einer Bibliotheksfunktion - system() in C++.

Verwenden Sie die Funktion system() in C++, um Shell-Befehle auszuführen

Die Funktion system() gehört seit einiger Zeit zur C-Standardbibliothek und kann ohne zusätzliche Bibliotheken auch in C++-Code eingebunden werden. Die Funktion wird verwendet, um einen Shell-Befehl aus dem aufrufenden Prozess auszuführen. Beachten Sie jedoch, dass system für spezielle Anwendungsfälle erstellt wird, wenn das aufrufende Programm einen einzelnen Kindprozess erzeugen und sofort auf dessen Beendigung warten muss. Somit wird die Funktion selbst mit mehreren Systemaufrufen implementiert, die als Teil der Systemschnittstelle verfügbar sind.

Wenn wir die UNIX-Umgebung annehmen, muss sich der Benutzer nicht direkt mit den Funktionen fork, exec und wait befassen, die eine neue Prozesserstellung/-bereinigung steuern. Das folgende Beispiel demonstriert den einfachsten Anwendungsfall für die Funktion system, die das Kommandozeilen-Dienstprogramm ls ausführt, um die Dateien im aktuellen Arbeitsverzeichnis zu drucken.

#include <iostream>

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

  return EXIT_SUCCESS;
}

Die Funktion system() erstellt normalerweise zwei Prozesse, um einen einzigen Befehl auszuführen. Es erstellt nämlich eine Shell mit einem exec-Aufruf und einem weiteren für den gegebenen Befehl, den die Shell ausführen wird. Es wirkt sich negativ auf die Leistung im Vergleich zur direkten Verwendung der zugrunde liegenden Systemaufrufe aus. Beachten Sie, dass, wenn wir den Befehl top mit system ausführen, das Programm wartet, bis der Benutzer top manuell verlässt folgendes Beispiel.

#include <iostream>

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

  return EXIT_SUCCESS;
}

Verwenden Sie system(nullptr), um zu überprüfen, ob Shell auf dem System verfügbar ist

Die Funktion system() verwendet als Argument eine einzelne Zeichenkette, die den Befehl darstellt, der von der Shell ausgeführt werden muss. Wenn wir nullptr oder NULL übergeben, wird ein Wert ungleich Null zurückgegeben, wenn ein Shell-Programm auf dem System verfügbar ist, oder wenn die Null zurückgegeben wird, zeigt dies an, dass die Shell nicht verfügbar ist.

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

Ausgabe:

shell is available on the system!

Verwenden Sie wstatus-Makros, um den Status des ausgeführten Befehls zu überprüfen

Wenn der Aufruf system keinen Kindprozess erzeugt, gibt er -1 zurück und setzt entsprechend errno. Wenn der Funktionsaufruf erfolgreich ist, ist der Rückgabewert der Beendigungsstatuscode der Shell, die den angegebenen Befehl ausgeführt hat. Außerdem ist dieser Beendigungsstatuscode derselbe wie der Beendigungscode des letzten ausgeführten Befehls. So kann man seinen Wert mit den wstatus-Makros überprüfen, die im wait-Systemaufruf man page beschrieben sind. Der nächste Codeausschnitt implementiert eine Funktion printWaitStatus, um den Rückgabewert system zu überprüfen und die Details zum letzten ausgeführten Befehl auszugeben.

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

Ausgabe:

(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