Unterschied zwischen “system” und “exec” in Linux?

Lesezeit: 6 Minuten

Benutzeravatar von Kamil
Kamil

Was ist der Unterschied zwischen system und exec Familienbefehle? Besonders möchte ich wissen, welcher von ihnen einen untergeordneten Prozess zum Arbeiten erstellt?

Benutzeravatar von Carl Norum
Karl Norum

system() ruft zu sh um Ihre Befehlszeile zu handhaben, damit Sie Platzhaltererweiterungen usw. erhalten können. exec() und seine Freunde ersetzen das aktuelle Prozessabbild durch ein neues Prozessabbild.

Mit system(), Ihr Programm läuft weiter und Sie erhalten einen Status über den von Ihnen aufgerufenen externen Befehl zurück. Mit exec()wird Ihr Prozess ausgelöscht.

Im Allgemeinen denke ich, dass Sie denken könnten system() als übergeordnete Schnittstelle. Sie könnten seine Funktionalität selbst duplizieren, indem Sie eine Kombination verwenden fork(), exec()und wait().

Um Ihre letzte Frage zu beantworten, system() bewirkt, dass ein untergeordneter Prozess erstellt wird, und die exec() Familie nicht. Sie müssten verwenden fork() dafür.

  • tut das system call erzeugt auch eine neue Shell, um den gegebenen Befehl auszuführen, oder er führt den Befehl in derselben Shell aus.

    – Krishna Oza

    5. Oktober 2016 um 9:51 Uhr

  • @Krishna_Oza – es gibt keine “gleiche Shell”, es sei denn, das Programm ruft auf system() ist selbst eine Schale. Ich bin mir nicht sicher, ob ich folgen kann. Meine Dokumentation hier sagt: “Die system() Funktion übergibt das Argument command an den Befehlsinterpreter sh(1).”

    – Karl Norum

    5. Oktober 2016 um 16:36 Uhr

  • Zitat aus system POSIX-Handbuch: Das system() Die Funktion soll sich so verhalten, als ob ein untergeordneter Prozess mit erstellt wurde fork()und der untergeordnete Prozess hat das Dienstprogramm sh mit aufgerufen execl() folgendermaßen: execl(<shell path>, "sh", "-c", command, (char *)0);.

    – patryk.beza

    26. Dezember 2016 um 9:06 Uhr


Die exec-Funktion ersetzt bei Erfolg das aktuell laufende Prozessabbild, es wird kein Kind erstellt (es sei denn, Sie machen das vorher selbst mit fork()). Die Funktion system() verzweigt einen untergeordneten Prozess und kehrt zurück, wenn die Ausführung des angegebenen Befehls beendet ist oder ein Fehler auftritt.

system() führt den angegebenen Befehl in einem untergeordneten Prozess aus, den er erzeugt. exec() ersetzt den aktuellen Prozess durch den Aufruf der neuen ausführbaren Datei, die Sie angeben. Wenn Sie einen untergeordneten Prozess mit erzeugen möchten execmüssen Sie fork() Ihren Prozess im Voraus.

So erstellen Sie einen Prozess:

  • fork(2)ein Systemaufruf direkt an den Kernel

So führen Sie ein Programm aus und ersetzen das aktuelle Bild:

  • execve(2)ein Systemaufruf direkt an den Kernel, normalerweise nur aufgerufen exec

So warten Sie, bis ein untergeordneter Prozess abgeschlossen ist:

  • wait(2)ein Systemaufruf direkt an den Kernel

So führen Sie ein Programm in einer Shell in einem untergeordneten Prozess aus und warten, bis es beendet ist:

  • system(3)eine Bibliotheksfunktion

Um das zu bekommen Manpages für alle oben genannten:

   $ man 2 fork execve wait
   $ man 3 system

Benutzeravatar von Clifford
Clifford

system() ruft die Standard-Befehlsshell Ihres Systems auf, die die als Argument übergebene Befehlszeichenfolge ausführt, die selbst weitere Prozesse erstellen kann oder nicht, die vom Befehl und dem System abhängen würden. In beiden Fällen wird zumindest ein Befehlsshellprozess erstellt.

Mit system() können Sie jeden Befehl aufrufen, während Sie mit exec() nur eine ausführbare Datei aufrufen können. Shellskripte und Batchdateien müssen von der Befehlsshell ausgeführt werden.

Grundsätzlich werden sie völlig unterschiedlich für unterschiedliche Zwecke verwendet. Außerdem ersetzt exec() den aufrufenden Prozess und kehrt nicht zurück. Ein nützlicherer Vergleich wäre zwischen system() und spawn(). Auch wenn system einfacher aufzurufen ist, gibt es einen Wert zurück, der Ihnen mitteilt, ob die Befehlsshell aufgerufen wurde, und nichts über den Erfolg des Befehls selbst aussagt. Mit spawn() erhalten Sie den Exit-Code des Prozesses; Konventionsgemäß wird Nicht-Null verwendet, um Fehlerbedingungen anzuzeigen. Wie exec() muss spawn() eine ausführbare Datei aufrufen, kein Shell-Skript oder eingebauter Befehl.

jap Benutzeravatar von jap
jap jap

Die Antwort von JonSpencer ist in Ordnung, außer dass child_status ein int sein muss (kein Zeiger auf int) und als Referenz an die Wait-Funktion übergeben werden muss.

Der Code wäre also im Wesentlichen derselbe, nur diese paar Dinge würden geändert:

#include <unistd.h>
#include <sys/wait.h>
#define NUMARGS 2

int main (int argc, char *argv[])
{
  pid_t child_pid, wait_pid;
  int child_status;
  char * exec_path = "/path/to/executable";
  char * child_args[NUMARGS] = {0,0};

  child_pid = fork();
  if (0 == child_pid)
  { // In child process
     ...
     int child_ret_code = execv(exec_path, child_args);  //or whichever flavor of exec() that floats your boat
     ... // if child_ret_code = -1, process execv() error return
  }
  else if (-1 == child_pid)
  {
     ... //process error return from fork
  }
  else if (0 < child_pid)
  {  // Parent process
     wait_pid = wait(&child_status);
     if (-1 == wait_pid)
     {
       ... //Process error return from wait()
     }
     else
     {  //  Good fork/exec/wait
        if (WIFEXITED(child_status))  // Child exited normally and hopefully returned exit code
        {
           int child_ret_code = WEXITSTATUS(child_status);
           ...  // Continue on as you would after call to system(3)
                //   except now you have the return code you needed
        }
     }
  }
}

(Weisen Sie darauf hin, dass ich noch nicht genug Ruf habe, um Jons Beitrag zu kommentieren, also habe ich ihn bearbeitet. Einige Leute haben die Ausgabe abgelehnt und mich gebeten, die Frage zu beantworten, anstatt sie zu bearbeiten, aber ich denke, dass es in diesem Fall viel einfacher und praktischer ist und klar, einen vorhandenen Code zu bearbeiten und nur einen kleinen Fehler zu korrigieren, als eine vollständige Antwort zum Kopieren / Einfügen / Ändern zu schreiben.) Wie auch immer, danke JonSpencer für Ihre Antwort, es war wirklich nützlich für mich!

Benutzeravatar von Kalpesh Dusane
Kalpesh Dusane


int system(const char *cmdstring);

Ex: system("date > file");


Im Algemeinen, System wird durch Aufruf implementiert Fork, Exec und Waitpidgibt es drei Arten von Rückgabewerten.

  • Wenn entweder der Fork fehlschlägt oder waitpid einen anderen Fehler als EINTR zurückgibt, gibt das System –1 zurück, wobei errno gesetzt ist, um den Fehler anzuzeigen.
  • Wenn die Ausführung fehlschlägt, was bedeutet, dass die Shell nicht ausgeführt werden kann, ist der Rückgabewert so, als hätte die Shell exit(127) ausgeführt.
  • Andernfalls sind alle drei Funktionen – fork, exec und waitpid – erfolgreich, und der Rückgabewert von system ist der Beendigungsstatus der Shell in dem für waitpid angegebenen Format.

Das Gabel Die Funktion besteht darin, einen neuen Prozess (den untergeordneten Prozess) zu erstellen, der dann die Ausführung eines anderen Programms durch Aufrufen einer der bewirkt Exekutive Funktionen. Wenn ein Prozess eine der exec-Funktionen aufruft, wird dieser Prozess vollständig durch das neue Programm ersetzt, und das neue Programm beginnt mit der Ausführung an seiner Hauptfunktion. Die Prozess-ID ändert sich nicht über eine Exec, da kein neuer Prozess erstellt wird; exec ersetzt lediglich den aktuellen Prozess – seine Text-, Daten-, Heap- und Stack-Segmente – durch ein brandneues Programm von der Festplatte.

Es gibt sechs verschiedene exec-Funktionen,


int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );

int execv(const char *pathname, char *const argv []);

int execle(const char *pathname, const char *arg0, .../* (char *)0, char *const envp[] */ );

int execve(const char *pathname, char *const argv[], char *const envp []);

int execlp(const char *filename, const char *arg0,... /* (char *)0 */ );

int execvp(const char *filename, char *const argv []);

1417390cookie-checkUnterschied zwischen “system” und “exec” in Linux?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy