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
What is the difference between the functions of the exec family of system calls like exec and execve?
提问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 exec
and 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 path
before 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 exec
system call -- this is usually used to refer to all the execXX
calls 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
v
in the name take an array parameter to specify theargv[]
array of the new program. The end of the arguments is indicated by an array element containingNULL
.The calls with
l
in 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 *)NULL
argument. You should always include the type cast, becauseNULL
is 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
e
in the name take an extra argument (or arguments in thel
case) 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 theargv
array: an array forexecve()
, separate arguments forexecle()
.The calls with
p
in the name search thePATH
environment 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 uppercaseP
). This is likeexecvp()
, but instead of getting the search path from thePATH
environment 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
environ
variable in the calling process to copy the existing environment to the program.- The letter
p
means that the functions takes a file name argument and uses the PATH environment variable to find the executable file. - The letter
l
means that the function takes a list of arguments and is mutually exclusive with the letterv
, which means that it takes an argv[] vector. The letter
e
means that the function takes anenvp[]
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 env
or printenv
on the shell or terminal you will get a list standard environment variables.
在 Linux 系统中,如果您在 shell 或终端上键入env
或printenv
,您将获得一个列表标准环境变量。
回答by Shravanya G
Within the exec family, there are functions that vary slightly in their capabilities and how they are called:
在 exec 系列中,有些函数的功能和调用方式略有不同:
Functions that contain the letter p in their names (
execvp
andexeclp
) 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.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'svarargs
mechanism.Functions that contain the letter e in their names (
execve
andexecle
) 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 formVARIABLE=value
.
名称中包含字母 p 的函数(
execvp
和execlp
)接受程序名称并在当前执行路径中按该名称搜索程序;不包含 p 的函数必须给出要执行的程序的完整路径。名称中包含字母 v 的函数(
execv
、execvp
和 execve)接受新程序的参数列表作为以 NULL 结尾的字符串指针数组。包含字母 l(execl
、execlp
和 execle)的函数使用 C 语言的varargs
机制接受参数列表。名称中包含字母 e 的函数 (
execve
和execle
) 接受一个额外的参数,一个环境变量数组。该参数应该是一个以 NULL 结尾的字符串指针数组。每个字符串的格式应为VARIABLE=value
.
回答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 系列”的其余部分(execl、execle、execv、execve、execvp等)都是内核系统调用(即execve)的 GLIBC 包装器。
回答by Prateek Joshi
Since all of these function belongs to exec() family, let me differentiate
according to extra characters
with 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 filename
specified or system will search for program file
in PATH
variable.
p : present => 要运行的程序的名称将取自filename
指定或系统将search for program file
在PATH
变量中。
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 filename
specified or system will search for program file
in PATH
variable.
p : present => 要运行的程序的名称将取自filename
指定或系统将search for program file
在PATH
变量中。
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