Linux exec 和 execve 等系统调用的 exec 系列函数有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20823371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:43:20  来源:igfitidea点击:

What is the difference between the functions of the exec family of system calls like exec and execve?

clinuxexecsystem-calls

提问by buddhi weerasinghe

I have been following a system programming course recently and I came through the system calls exec()and execve(). So far I cannot find any difference between these two, Even the Wikipedia does not give a clear explanation, so is there a difference between exec()and execve().

我最近一直在学习系统编程课程,我通过系统调用exec()execve() 来了。到目前为止我找不到这两者之间的任何区别,甚至维基百科也没有给出明确的解释,所以exec()execve()之间有区别。

And someone please could give brief descriptions about exec family system calls such as execl(), execv(), execle(), execvp().

有人可以简要描述 exec 系列系统调用,例如execl()execv()execle()execvp()

采纳答案by Noam Rathaus

Use man execand read:

使用man exec和阅读:

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

execv

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

So you pass an array as parameters

所以你传递一个数组作为参数

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

Almost the same, but not as an array, but rather as a list of values (strings), followed by an array the designates the environment.

几乎相同,但不是作为数组,而是作为值(字符串)列表,后跟指定环境的数组。

Here:

这里:

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

You are calling a file, without path, so it expects you to be already in the right pathbefore calling.

您正在调用一个没有路径的文件,因此它希望您path在调用之前已经在正确的位置。

Last but not least:

最后但并非最不重要的:

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

Similar to previous one, but now you have two arrays, for arguments and environment variables.

与前一个类似,但现在您有两个数组,分别用于参数和环境变量。

回答by Barmar

There is no execsystem call -- this is usually used to refer to all the execXXcalls as a group. They all do essentially the same thing: loading a new program into the current process, and provide it with arguments and environment variables. The differences are in how the program is found, how the arguments are specified, and where the environment comes from.

没有exec系统调用——这通常用于将所有execXX调用称为一个组。它们本质上都做同样的事情:将一个新程序加载到当前进程中,并为其提供参数和环境变量。不同之处在于如何找到程序、如何指定参数以及环境来自何处。

  • The calls with vin the name take an array parameter to specify the argv[]array of the new program. The end of the arguments is indicated by an array element containing NULL.

  • The calls with lin the name take the arguments of the new program as a variable-length argument list to the function itself. The end of the arguments is indicated by a (char *)NULLargument. You should always include the type cast, because NULLis allowed to be an integer constant, and default argument conversions when calling a variadic function won't convert that to a pointer.

  • The calls with ein the name take an extra argument (or arguments in the lcase) to provide the environment of the new program; otherwise, the program inherits the current process's environment. This is provided in the same way as the argvarray: an array for execve(), separate arguments for execle().

  • The calls with pin the name search the PATHenvironment variable to find the program if it doesn't have a directory in it (i.e. it doesn't contain a /character). Otherwise, the program name is always treated as a path to the executable.

  • FreeBSD 5.2 added another variant: execvP(with uppercase P). This is like execvp(), but instead of getting the search path from the PATHenvironment variable, it's an explicit parameter to the function:

  • v名称中带有的调用带有一个数组参数来指定argv[]新程序的数组。参数的结尾由包含 的数组元素指示NULL

  • l名称中带有 的调用将新程序的参数作为函数本身的可变长度参数列表。参数的结尾由参数指示(char *)NULL。您应该始终包括类型转换,因为NULL允许是整数常量,并且调用可变参数函数时的默认参数转换不会将其转换为指针。

  • e名称中带有的调用需要一个额外的参数(或l情况下的参数)来提供新程序的环境;否则,程序将继承当前进程的环境。这以与argv数组相同的方式提供:用于 的数组,用于 的execve()单独参数execle()

  • 如果程序中没有目录(即它不包含字符)p,则名称中带有 的调用会搜索PATH环境变量以查找程序/。否则,程序名称始终被视为可执行文件的路径。

  • FreeBSD 5.2 添加了另一个变体:(execvP大写P)。这就像execvp(),但不是从PATH环境变量中获取搜索路径,而是函数的显式参数:

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

回答by Barmar

The arguments are different for these functions.

这些函数的参数是不同的。

  • The function execl, execlp, and execle require each of the command line arguments to the new program to be specified as separate arguments.

  • The execv, execvp and execve, we have to build an array of pointers to the arguments, and the address of this array is the argument to these three functions.

  • The execve, execle functions allow us to pass the pointer to an array of pointers to the environment strings. The other four functions use the environvariable in the calling process to copy the existing environment to the program.

  • The letter pmeans that the functions takes a file name argument and uses the PATH environment variable to find the executable file.
  • The letter lmeans that the function takes a list of arguments and is mutually exclusive with the letter v, which means that it takes an argv[] vector.
  • The letter emeans that the function takes an envp[]array instead of using the current environment.

  • The new program inherits the following additional features from the calling process.

  • 函数 execl、execlp 和 execle 要求将新程序的每个命令行参数指定为单独的参数。

  • execv、execvp和execve,我们要构建一个指向参数的指针数组,这个数组的地址就是这三个函数的参数。

  • execve、execle 函数允许我们将指针传递给指向环境字符串的指针数组。其他四个函数environ在调用过程中使用该变量将现有环境复制到程序中。

  • 该字母p表示函数采用文件名参数并使用 PATH 环境变量来查找可执行文件。
  • 字母l表示该函数采用参数列表,并且与字母 互斥v,这意味着它采用 argv[] 向量。
  • 该字母e表示该函数接受一个envp[]数组而不是使用当前环境。

  • 新程序从调用过程中继承了以下附加功能。

    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.
  • The real user ID and the real group ID remain the same across the exec but the effective IDs can change, depending on the status of the set-user-id and the set-group-id bits for the program file executed.
  • 实际用户 ID 和实际组 ID 在整个 exec 中保持不变,但有效 ID 可以更改,具体取决于 set-user-id 和执行的程序文件的 set-group-id 位的状态。

回答by Asif

Main Idea

大意

exec() family of functions replaces existing process image with a new process image. This is a marked difference from fork() system call where the parent and child processes co-exist in the memory.

exec() 系列函数用新的进程映像替换现有的进程映像。这与 fork() 系统调用显着不同,其中父进程和子进程在内存中共存。

exec() family of functions

exec() 函数族

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

The filename is the file of the new process image.

文件名是新过程映像的文件。

argv represents an array of null-terminated strings.The last element of this array must be a null pointer.

argv 表示以空字符结尾的字符串数组。该数组的最后一个元素必须是空指针。

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

Same as execv but the arguments are provided as an individual string (separated by commas) instead of an array/vector.

与 execv 相同,但参数作为单独的字符串(用逗号分隔)而不是数组/向量提供。

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

Same as execv but it permits to specify environment variables for new process image.

与 execv 相同,但它允许为新的进程映像指定环境变量。

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

Same as execl but it permits to specify environment variables for new process image.

与 execl 相同,但它允许为新的进程映像指定环境变量。

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

Same as execv function but it searches standard environment variable PATH to find the filename if the filename does not contain a slash.

与 execv 函数相同,但如果文件名不包含斜杠,它会搜索标准环境变量 PATH 以查找文件名。

Here is a list of standard environment variable:

这是标准环境变量的列表:

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

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

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

Same as execl function except the fact that if performs the filename search as the execvp function.

除了 if 执行文件名搜索作为 execvp 函数之外,与 execl 函数相同。

Note

笔记

In a Linux system, if you type envor printenvon the shell or terminal you will get a list standard environment variables.

在 Linux 系统中,如果您在 shell 或终端上键入envprintenv,您将获得一个列表标准环境变量。

回答by Shravanya G

Within the exec family, there are functions that vary slightly in their capabilities and how they are called:

在 exec 系列中,有些函数的功能和调用方式略有不同:

  1. Functions that contain the letter p in their names (execvpand execlp) accept a program name and search for a program by that name in the current execution path; functions that don't contain the p must be given the full path of the program to be executed.

  2. Functions that contain the letter v in their names (execv, execvp, and execve) accept the argument list for the new program as a NULL-terminated array of pointers to strings. Functions that contain the letter l (execl, execlp, and execle) accept the argument list using the C language's varargsmechanism.

  3. Functions that contain the letter e in their names (execveand execle) accept an additional argument, an array of environment variables.The argument should be a NULL-terminated array of pointers to character strings. Each character string should be of the form VARIABLE=value.

  1. 名称中包含字母 p 的函数(execvpexeclp)接受程序名称并在当前执行路径中按该名称搜索程序;不包含 p 的函数必须给出要执行的程序的完整路径。

  2. 名称中包含字母 v 的函数(execvexecvp和 execve)接受新程序的参数列表作为以 NULL 结尾的字符串指针数组。包含字母 l(execlexeclp和 execle)的函数使用 C 语言的varargs机制接受参数列表。

  3. 名称中包含字母 e 的函数 (execveexecle) 接受一个额外的参数,一个环境变量数组。该参数应该是一个以 NULL 结尾的字符串指针数组。每个字符串的格式应为VARIABLE=value.

Source

来源

回答by axisofadvance

To answer the first part of your question, in the context of Linux specifically, there is only one system call and it's execve(not exec). The remainder of the so called "exec family" (execl, execle, execv, execve, execvp, etc.) are all GLIBC wrappers for for the kernel's system call, that is execve.

要回答问题的第一部分,特别是在 Linux 的上下文中,只有一个系统调用,它是execve(不是exec)。所谓的“exec 系列”的其余部分(execlexecleexecvexecveexecvp等)都是内核系统调用(即execve)的 GLIBC 包装器。

回答by Prateek Joshi

Since all of these function belongs to exec() family, let me differentiateaccording to extra characterswith the meanings,

由于所有这些函数都属于 exec() 家族,让我differentiate按照extra characters含义,

1.execve():

1.exec ve():

p : not present => name of the program to run will be taken from pathname

p : 不存在 => 要运行的程序的名称将取自 pathname

v : present => argument will be passed as array

v : present => 参数将作为 array

e : present => environment will be taken from envp argument

e : 存在 => 环境将从 envp argument

2.execle():

2.exec le():

p : not present => name of the program to run will be taken from pathname

p : 不存在 => 要运行的程序的名称将取自 pathname

l : present => argument will be passed as list

l : present => 参数将作为 list

e : present => environment will be taken from envp argument

e : 存在 => 环境将从 envp argument

3.execlp():

3.exec lp():

p : present => name of the program to run will be taken from filenamespecified or system will search for program filein PATHvariable.

p : present => 要运行的程序的名称将取自filename指定或系统将search for program filePATH变量中。

l : present => argument will be passed as list

l : present => 参数将作为 list

e : not present => environment will be taken from caller's environ

e : 不存在 => 环境将从 caller's environ

4.execvp():

4.exec vp():

p : present => name of the program to run will be taken from filenamespecified or system will search for program filein PATHvariable.

p : present => 要运行的程序的名称将取自filename指定或系统将search for program filePATH变量中。

v : present => argument will be passed as array

v : present => 参数将作为 array

e : not present => environment will be taken from caller's environ

e : 不存在 => 环境将从 caller's environ

5.execv():

5.exec v():

p : not present => name of the program to run will be taken from pathname

p : 不存在 => 要运行的程序的名称将取自 pathname

v : present => argument will be passed as array

v : present => 参数将作为 array

e : not present => environment will be taken from caller's environ

e : 不存在 => 环境将从 caller's environ

6.execl():

6.exec l():

p : not present => name of the program to run will be taken from pathname

p : 不存在 => 要运行的程序的名称将取自 pathname

l : present => argument will be passed as list

l : present => 参数将作为 list

e : not present => environment will be taken from caller's environ

e : 不存在 => 环境将从 caller's environ