SYSTEM(3)

BEZEICHNUNG
system - einen Shell-Befehl ausführen

ÜBERSICHT
#include <stdlib.h>

int system(const char *Befehl);

BESCHREIBUNG
Die Bibliotheksfunktion system() verwendet fork(2), um einen Kindprozess zu erzeugen, der den in Befehl angegebenen Shell-Befehl mittels execl(3) wie folgt ausführt:

    execl("/bin/sh", "sh", "-c", Befehl, (char *) NULL);

system() kehrt nach der Ausführung zurück.

Während der Ausführung des Befehls wird SIGCHLD blockiert und SIGINT sowie SIGQUIT werden in den system()-Prozessaufrufen ignoriert (diese Signale werden gemäß ihrer Voreinstellungen innerhalb des Kindprozesses behandelt, der Befehl ausführt).

Falls Befehl NULL ist, gibt system() einen Status zurück, der angibt, ob auf dem System eine Shell verfügbar ist.

RÜCKGABEWERT
Der Rückgabewert von system() ist einer der folgenden:

*   Falls Befehl NULL ist, ein Wert ungleich Null, wenn die Shell verfügbar ist oder Null, wenn nicht.

*   Falls ein Kindprozess nicht erstellt werden konnte oder sein Status nicht erneut geholt werden kann, ist der Rückgabewert -1 und errno wird gesetzt, um den Fehler anzuzeigen.

*   Falls in dem Kindprozess keine Shell ausgeführt werden kann, ist der Rückgabewert so, als ob die Shell im Kindprozess durch den Aufruf von _exit(2) mit dem Status 127 beendet worden wäre.

*   Falls alle Systemaufrufe erfolgreich waren, dann wird der Rückgabewert der Status beim Beenden der Kind-Shell sein, die zum Ausführen von Befehl benutzt wurde. (Der Status beim Beenden einer Shell ist der Status beim Beenden des letzten von ihr ausgeführten Befehls.)

In den letzten beiden Fällen ist der Rückgabewert ein »Wartestatus«, der mittels der in waitpid(2) beschriebenen Makros untersucht werden kann (d.h. WIFEXITED(), WEXITSTATUS() und so weiter).

system() beeinflusst nicht den Wartestatus anderer Kindprozesse.

FEHLER
system() kann mit den gleichen Fehlern wie fork(2) fehlschlagen.

ATTRIBUTE
Siehe attributes(7) für eine Erläuterung der in diesem Abschnitt verwandten Ausdrücke.
Schnittstelle | Attribut | Wert
system() | Multithread-Fähigkeit | MT-Safe

KONFORM ZU
POSIX.1-2001, POSIX.1-2008, C89, C99.

ANMERKUNGEN
system() stellt Einfachheit und Komfort bereit. Es behandelt alle Einzelheiten beim Aufrufen von fork(2), execl(3) und waitpid(2) sowie die nötigen Manipulationen von Signalen. Zusätzlich führt die Shell die üblichen Ersetzungen von E/A-Umleitungen für Befehl durch. Am stärksten geht dies zu Lasten der Leistungsfähigkeit: Zum Erzeugen des Prozesses, der die Shell startet, sowie zum Ausführen der Shell werden zusätzliche Systemaufrufe benötigt.

Falls das Feature-Test-Makro _XOPEN_SOURCE definiert wurde (vor dem Einbinden irgendwelcher Header-Dateien), dann werden die in waitpid(2) beschriebenen Makros (WEXITSTATUS(), etc.) durch das Einbinden von <stdlib.h> zur Verfügung gestellt.

Wie erwähnt, ignoriert system() SIGINT und SIGQUIT. Dies kann dazu führen, dass Programme, die es in einer Schleife aufrufen, nicht mehr unterbrochen werden können, sofern sie nicht aufpassen, dass sie selbst den Exit-Status des Kindprozesses prüfen. Zum Beispiel:

    while (etwas) {
        int ret = system("foo");
        if (WIFSIGNALED(ret) &&
            (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT))
                break;
    }

Laut POSIX.1 ist nicht spezifiziert, ob mittels pthread_atfork(3) registrierte Handler während der Ausführung von system() aufgerufen werden. In der Glibc-Implementierung werden solche Handler nicht aufgerufen.

In Glibc-Versionen vor 2.1.3 wurde die Verfügbarkeit von /bin/sh genaugenommen nicht überprüft, wenn Befehl NULL war. Stattdessen wurde angenommen, es sei verfügbar und system() gab in diesem Fall immer 1 zurück. Seit Glibc 2.1.3 wird diese Überprüfung durchgeführt, da, obwohl POSIX.1-2001 eine entsprechende Implementierung benötigt, um eine Shell zur Verfügung zu stellen, diese Shell nicht verfügbar oder ausführbar sein könnte, wenn das aufrufende Programm vorher chroot(2) aufrief (was nicht durch POSIX.1-2001 spezifiziert ist).

Es ist möglich, dass ein Shell-Befehl mit dem Status 127 beendet wird. Dies ergibt einen Rückgabewert von system(), der nicht von dem Fall zu unterscheiden ist, in dem eine Shell nicht im Kindprozess ausgeführt werden kann.

  Warnungen
Benutzen Sie system() nicht aus einem privilegierten Programm (einem Set-User-ID- oder Set-Group-ID-Programm oder einem mit Capabilities), da merkwürdige Werte für einige Umgebungsvariablen benutzt werden könnten, die möglicherweise die Systemintegrität untergraben. Beispielsweise könnte PATH so verändert sein, dass ein beliebiges Programm mit Privilegien ausgeführt wird. Benutzen Sie stattdessen die Funktionen der exec(3)-Familie, jedoch nicht execlp(3) oder execvp(3) (die auch die Umgebungsvariable PATH zur Suche nach Programmen verwenden).

Genaugenommen wird system() aus Programmen mit SUID- oder SGID-Rechten nicht richtig auf Systemen funktionieren, auf denen /bin/sh Bash in der Version 2 vorliegt, da Bash 2 als Sicherheitsmaßnahme beim Start Privilegien verwirft. (Debian benutzt eine andere Shell, dash(1), die dies unterlässt, wenn sie als sh aufgerufen wird.

Sämtliche Benutzereingaben, die als Teil von command eingesetzt werden, sollten sorgfältig bereinigt werden, um sicherzustellen, dass unerwartete Shell-Befehle oder Befehlsoptionen nicht ausgeführt werden. Solche Risiken sind besonders schwerwiegend, wenn system() aus einem privilegierten Programm verwandt wird.

FEHLER
Falls der Befehlsname mit einem Minuszeichen beginnt, interpretiert sh(1) den Befehlsnamen als Option, was in einem nicht definierten Verhalten resultiert (siehe die Option -c zu sh(1)). Um dieses Problem zu umgehen, stellen Sie dem Befehl ein Leerzeichen voran, wie im folgenden aufruf:

        system(" -ungünstiger-Befehlsname");

SIEHE AUCH
sh(1), execve(2), fork(2), sigaction(2), sigprocmask(2), wait(2), exec(3), signal(7)

KOLOPHON
Diese Seite ist Teil der Veröffentlichung 5.13 des Projekts Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Patrick Rother <krd@gulu.net>, Chris Leick <c.leick@vollbio.de>, Dr. Tobias Quathamer <toddy@debian.org>, Helge Kreutzmann <debian@helgefjell.de> und Mario Blättermann <mario.blaettermann@gmail.com> erstellt.

Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 (https://www.gnu.org/licenses/gpl-3.0.html) oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Übersetzer (debian-l10n-german@lists.debian.org).