Die system()-Funktion in C++
-
Verwenden Sie die Funktion
system()
in C++, um Shell-Befehle auszuführen -
Verwenden Sie
system(nullptr)
, um zu überprüfen, ob Shell auf dem System verfügbar ist -
Verwenden Sie
wstatus
-Makros, um den Status des ausgeführten Befehls zu überprüfen
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
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