Was ist der Unterschied zwischen den Funktionen der exec-Familie von Systemaufrufen wie exec und execve?

Lesezeit: 8 Minuten

buddhi weerasinghes Benutzeravatar
buddhi weerasinghe

Ich habe kürzlich an einem Systemprogrammierkurs teilgenommen und bin durch die Systemaufrufe gekommen ausführen() und ausführen(). Bisher kann ich keinen Unterschied zwischen diesen beiden finden, selbst die Wikipedia gibt keine klare Erklärung, also gibt es einen Unterschied zwischen ausführen() und ausführen().

Und jemand könnte bitte kurze Beschreibungen über Systemaufrufe der Exec-Familie geben, wie z execl(), ausführen(), execle(), execvp().

  • Wikipedia ist nicht die primäre Informationsquelle für UNIX-Systemaufrufe, aber die Manpages sind: For the exec*()-Familie von Funktionen, die Sie vielleicht hier lesen möchten: man7.org/linux/man-pages/man3/execl.3.html

    – alk

    29. Dezember 2013 um 9:17 Uhr


  • Lesen Sie auch Fortgeschrittene Linux-Programmierung

    – Basile Starynkevitch

    29. Dezember 2013 um 9:44 Uhr

  • mögliches Duplikat von Wofür werden die verschiedenen Versionen von exec in C++ verwendet?

    – Ciro Santilli OurBigBook.com

    9. Mai 2015 um 15:58 Uhr

Benutzeravatar von Barmar
Barmar

Es gibt kein exec Systemaufruf – dies wird normalerweise verwendet, um sich auf alle zu beziehen execXX Anrufe als Gruppe. Sie alle tun im Wesentlichen dasselbe: Laden eines neuen Programms in den aktuellen Prozess und Versehen mit Argumenten und Umgebungsvariablen. Die Unterschiede bestehen darin, wie das Programm gefunden wird, wie die Argumente angegeben werden und woher die Umgebung kommt.

  • Die Anrufe mit v im Namen nehmen Sie einen Array-Parameter, um die anzugeben argv[] Array des neuen Programms. Das Ende der Argumente wird durch ein Array-Element angezeigt, das enthält NULL.

  • Die Anrufe mit l im Namen nehmen die Argumente des neuen Programms als Argumentliste variabler Länge in die Funktion selbst auf. Das Ende der Argumente wird durch a angezeigt (char *)NULL Streit. Sie sollten immer die Typumwandlung angeben, weil NULL darf eine ganzzahlige Konstante sein, und Konvertierungen von Standardargumenten beim Aufrufen einer variadischen Funktion konvertieren dies nicht in einen Zeiger.

  • Die Anrufe mit e im Namen nehmen Sie ein zusätzliches Argument (oder Argumente in der l Fall), um die Umgebung des neuen Programms bereitzustellen; andernfalls erbt das Programm die Umgebung des aktuellen Prozesses. Dies wird auf die gleiche Weise bereitgestellt wie die argv Array: ein Array für execve()getrennte Argumente für execle().

  • Die Anrufe mit p in der Namenssuche die PATH Umgebungsvariable, um das Programm zu finden, wenn es kein Verzeichnis enthält (dh es enthält keine / Charakter). Andernfalls wird der Programmname immer als Pfad zur ausführbaren Datei behandelt.

  • FreeBSD 5.2 hat eine weitere Variante hinzugefügt: execvP (mit Großbuchstaben P). Das ist wie execvp()aber anstatt den Suchpfad von der PATH Umgebungsvariable, es ist ein expliziter Parameter für die Funktion:

int execvP(const char *file, const char *search_path, char *const argv[]);

  • Der einzige Unterschied zwischen den obigen Systemaufrufen besteht in den Parametern. Ist das der Fall? Wenn ja, ist das Endergebnis aller Systemaufrufe der Exec-Familie die Ausführung eines Programms (mit unterschiedlichen Parametern)?

    – buddhi weerasinghe

    29. Dezember 2013 um 8:37 Uhr

  • Eigentlich die nur Systemaufruf ist Exekutive(2) und alle anderen exec* Funktionen wickeln es ein.

    – Basile Starynkevitch

    29. Dezember 2013 um 9:43 Uhr

  • Das weiß ich, aber die Unterscheidung ist nicht wirklich wichtig, es sei denn, Sie sind ein Kernel-Entwickler.

    – Barmar

    29. Dezember 2013 um 9:44 Uhr

  • Vielen Dank. Gibt es einen Unterschied zwischen der Beliebtheit dieser exec*-Funktionen? Ich habe nicht viele Beispiele gesehen, aber es scheint mir, dass execlp() (und vielleicht execvp()) am häufigsten verwendet wird?

    – Tim

    28. November 2018 um 15:23 Uhr


Benutzeravatar von Noam Rathaus
Noam Rathaus

Verwenden man exec und lese:

The execv(), execvp(), and execvpe() functions provide an array of pointers to 
null-terminated strings that represent the argument list available to the new program. 
The first argument, by convention, should point to the filename associated with the file 
being executed. The array of pointers must be terminated by a NULL pointer. 

execv

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

Sie übergeben also ein Array als Parameter

int execle(const char *path, const char *arg,
              ..., char * const envp[]);

Fast genauso, aber nicht als Array, sondern als Liste von Werten (Strings), gefolgt von einem Array, das die Umgebung bezeichnet.

Hier:

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

Sie rufen eine Datei ohne Pfad auf, also erwartet sie, dass Sie bereits im Recht sind path vor dem Anruf.

Zu guter Letzt:

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

Ähnlich wie beim vorherigen, aber jetzt haben Sie zwei Arrays für Argumente und Umgebungsvariablen.

  • Der einzige Unterschied zwischen den obigen Systemaufrufen besteht in den Parametern. Ist das der Fall? Wenn ja, ist das Endergebnis aller Systemaufrufe der Exec-Familie die Ausführung eines Programms (mit unterschiedlichen Parametern)?

    – buddhi weerasinghe

    29. Dezember 2013 um 8:36 Uhr

  • Nur andere Parameter, nichts anderes ist anders

    – Noam Rathaus

    29. Dezember 2013 um 8:39 Uhr

Da alle diese Funktionen zur Familie exec() gehören, lassen Sie mich differentiate entsprechend extra characters mit den Bedeutungen,

1.execve():

p : nicht vorhanden => Name des auszuführenden Programms wird übernommen pathname

v : present => Argument wird übergeben als array

e : present => Umgebung wird entnommen envp argument

2.execle():

p : nicht vorhanden => Name des auszuführenden Programms wird übernommen pathname

l : present => Argument wird übergeben als list

e : present => Umgebung wird entnommen envp argument

3.execlp():

p : present => Name des auszuführenden Programms wird übernommen filename angegeben oder System wird search for program file in PATH Variable.

l : present => Argument wird übergeben als list

e : nicht vorhanden => Umgebung wird entnommen caller's environ

4.execvp():

p : present => Name des auszuführenden Programms wird übernommen filename angegeben oder System wird search for program file in PATH Variable.

v : present => Argument wird übergeben als array

e : nicht vorhanden => Umgebung wird entnommen caller's environ

5.execv():

p : nicht vorhanden => Name des auszuführenden Programms wird übernommen pathname

v : present => Argument wird übergeben als array

e : nicht vorhanden => Umgebung wird entnommen caller's environ

6.execl():

p : nicht vorhanden => Name des auszuführenden Programms wird übernommen pathname

l : present => Argument wird übergeben als list

e : nicht vorhanden => Umgebung wird entnommen caller's environ

Benutzeravatar von Asif
Als ob

Hauptidee

Die Funktionsfamilie exec() ersetzt ein vorhandenes Prozessabbild durch ein neues Prozessabbild. Dies ist ein deutlicher Unterschied zum Systemaufruf fork(), bei dem Eltern- und Kindprozesse im Speicher koexistieren.

exec() Familie von Funktionen

int execv (const char *filename, char *const argv[])

Der Dateiname ist die Datei des neuen Prozessabbilds.

argv stellt ein Array von nullterminierten Strings dar. Das letzte Element dieses Arrays muss ein Nullzeiger sein.

int execl (const char *filename, const char *arg0, …)

Dasselbe wie bei execv, aber die Argumente werden als einzelne Zeichenfolge (durch Kommas getrennt) anstelle eines Arrays/Vektors bereitgestellt.

int execve (const char *filename, char *const argv[], char *const env[])

Dasselbe wie execv, erlaubt jedoch die Angabe von Umgebungsvariablen für ein neues Prozessabbild.

int execle (const char *filename, const char *arg0, …, char *const env[])

Dasselbe wie execl, erlaubt jedoch die Angabe von Umgebungsvariablen für ein neues Prozessabbild.

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

Identisch mit der execv-Funktion, aber sie durchsucht die Standard-Umgebungsvariable PATH, um den Dateinamen zu finden, wenn der Dateiname keinen Schrägstrich enthält.

Hier ist eine Liste der Standardumgebungsvariablen:

https://www.gnu.org/software/libc/manual/html_node/Standard-Environment.html#Standard-Environment

int execlp (const char *filename, const char *arg0, …)

Identisch mit der execl-Funktion, außer der Tatsache, dass if die Dateinamensuche wie die execvp-Funktion durchführt.

Notiz

In einem Linux-System, wenn Sie eingeben env oder printenv Auf der Shell oder dem Terminal erhalten Sie eine Liste von Standardumgebungsvariablen.

Die Argumente sind für diese Funktionen unterschiedlich.

  • Die Funktionen execl, execlp und execle erfordern, dass jedes der Befehlszeilenargumente für das neue Programm als separate Argumente angegeben wird.

  • Bei execv, execvp und execve müssen wir ein Array von Zeigern auf die Argumente erstellen, und die Adresse dieses Arrays ist das Argument für diese drei Funktionen.

  • Die Funktionen execve, execle ermöglichen es uns, den Zeiger auf ein Array von Zeigern auf die Umgebungszeichenfolgen zu übergeben. Die anderen vier Funktionen verwenden die environ Variable im aufrufenden Prozess, um die vorhandene Umgebung in das Programm zu kopieren.

  • Der Buchstabe p bedeutet, dass die Funktion ein Dateinamenargument akzeptiert und die PATH-Umgebungsvariable verwendet, um die ausführbare Datei zu finden.
  • Der Buchstabe l bedeutet, dass die Funktion eine Liste von Argumenten verwendet und sich gegenseitig mit dem Buchstaben ausschließt vwas bedeutet, dass ein argv benötigt wird[] Vektor.
  • Der Buchstabe e bedeutet, dass die Funktion an nimmt envp[] array, anstatt die aktuelle Umgebung zu verwenden.

  • Das neue Programm erbt die folgenden zusätzlichen Merkmale vom aufrufenden Prozess.

    Process ID and the Parent Process ID
    Real user ID and Real Group ID
    Supplementary group IDs
    Process group ID
    Session ID
    Controlling terminal
    Time left until alarm clock
    Current working directory
    Root directory
    File mode creation mask
    File locks
    Process signal mask
    Pending signals
    Resource limits
    Values for tms_utime, tms_stime, tms_cutime, and tms_cstime.
  • Die reale Benutzer-ID und die reale Gruppen-ID bleiben in der gesamten Ausführung gleich, aber die effektiven IDs können sich ändern, abhängig vom Status der set-user-id- und set-group-id-Bits für die ausgeführte Programmdatei.

Benutzeravatar von axisofadvance
Achse des Vorschubs

Um den ersten Teil Ihrer Frage zu beantworten, gibt es speziell im Kontext von Linux nur einen Systemaufruf und es ist ausführen (nicht Exekutive). Der Rest der sogenannten “Exec-Familie” (exkl, Exekel, Exekutive, ausführen, ausführenusw.) sind alle GLIBC-Wrapper für den Systemaufruf des Kernels, das heißt ausführen.

rodgdors Benutzeravatar
rodgdor

Innerhalb der Exec-Familie gibt es Funktionen, die sich in ihren Fähigkeiten und ihrer Bezeichnung leicht unterscheiden:

  1. Funktionen, die den Buchstaben p in ihrem Namen enthalten (execvp und execlp) Akzeptiere einen Programmnamen und suche im aktuellen Ausführungspfad nach einem Programm mit diesem Namen; Funktionen, die das p nicht enthalten, muss der vollständige Pfad des auszuführenden Programms angegeben werden.

  2. Funktionen, die den Buchstaben v in ihrem Namen enthalten (execv, execvp, und execve) akzeptieren die Argumentliste für das neue Programm als NULL-terminiertes Array von Zeigern auf Strings. Funktionen, die den Buchstaben l enthalten (execl, execlpund execle) akzeptieren die Argumentliste unter Verwendung der C-Sprache varargs Mechanismus.

  3. Funktionen, die den Buchstaben e in ihrem Namen enthalten (execve und execle) akzeptieren ein zusätzliches Argument, ein Array von Umgebungsvariablen. Das Argument sollte ein NULL-terminiertes Array von Zeigern auf Zeichenfolgen sein. Jede Zeichenkette sollte die Form haben VARIABLE=value.

Quelle

1409110cookie-checkWas ist der Unterschied zwischen den Funktionen der exec-Familie von Systemaufrufen wie exec und execve?

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

Privacy policy