我最近一直在关注系统编程课程,我通过系统调用 exec()和 execve()来完成。到目前为止,我发现这两者之间没有任何区别,即使维基百科也没有给出明确的解释,所以 exec()和 execve()之间有区别。
请有人详细说明exec家庭系统调用,例如 execl(), execv(), execle(),的 execvp()
答案 0 :(得分:41)
没有exec
系统调用 - 这通常用于将所有execXX
个调用称为一个组。它们都基本上做同样的事情:将新程序加载到当前进程中,并为其提供参数和环境变量。不同之处在于如何找到程序,如何指定参数以及环境来自何处。
名称中带v
的调用采用数组参数来指定新程序的argv[]
数组。
名称中带l
的调用将新程序的参数作为函数本身的可变长度参数列表。
名称中带e
的调用需要额外的参数来提供新程序的环境;否则,程序会继承当前进程的环境。
名称中p
的调用会搜索PATH
环境变量,以便在程序中没有目录时找到该程序(即它不包含{{ 1}}字符)。否则,程序名称始终被视为可执行文件的路径。
答案 1 :(得分:17)
使用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
int execv(const char *path, char *const argv[]);
所以你传递一个数组作为参数
int execle(const char *path, const char *arg,
..., char * const envp[]);
几乎相同,但不是作为数组,而是作为值列表(字符串),后跟数组指定环境。
下面:
int execvp(const char *file, char *const argv[]);
您正在调用一个没有路径的文件,所以它希望您在调用前已经在path
右侧。
最后但并非最不重要:
int execve(const char *filename, char *const argv[],
char *const envp[]);
与前一个类似,但现在你有两个数组,用于参数和环境变量。
答案 2 :(得分:5)
由于所有这些函数都属于exec()系列,因此根据differentiate
赋予我extra characters
含义,
1.exec的已经强>():
p:not present =>要运行的程序的名称将取自pathname
v:present =>参数将作为array
e:present =>环境将取自envp argument
2.exec的文件强>():
p:not present =>要运行的程序的名称将取自pathname
l:present =>参数将作为list
e:present =>环境将取自envp argument
3.exec的 LP 强>():
p:present =>要运行的程序的名称将从指定的filename
或search for program file
变量中的系统PATH
获取。
l:present =>参数将作为list
e:not present =>环境将取自caller's environ
4.exec的 VP 强>():
p:present =>要运行的程序的名称将从指定的filename
或search for program file
变量中的系统PATH
获取。
v:present =>参数将作为array
e:not present =>环境将取自caller's environ
5.exec的 v 强>():
p:not present =>要运行的程序的名称将取自pathname
v:present =>参数将作为array
e:not present =>环境将取自caller's environ
6.exec的升强>():
p:not present =>要运行的程序的名称将取自pathname
l:present =>参数将作为list
e:not present =>环境将取自caller's environ
答案 3 :(得分:2)
这些函数的参数不同。
函数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.
答案 4 :(得分:2)
exec()函数系列用新的过程映像替换现有的过程映像。这与fork()系统调用有明显区别,其中父进程和子进程在内存中共存。
int execv (const char *filename, char *const argv[])
文件名是新过程映像的文件。
argv表示以null结尾的字符串数组。此数组的最后一个元素必须是空指针。
int execl (const char *filename, const char *arg0, …)
与execv相同,但参数以单个字符串(用逗号分隔)而不是数组/向量提供。
int execve (const char *filename, char *const argv[], char *const env[])
与execv相同,但它允许为新过程映像指定环境变量。
int execle (const char *filename, const char *arg0, …, char *const env[])
与execl相同,但它允许为新过程映像指定环境变量。
int execvp (const char *filename, char *const argv[])
与execv函数相同,但如果文件名不包含斜杠,它会搜索标准环境变量PATH以查找文件名。
以下是标准环境变量列表:
https://www.gnu.org/software/libc/manual/html_node/Standard-Environment.html#Standard-Environment
int execlp (const char *filename, const char *arg0, …)
与execl函数相同,除了if执行文件名搜索作为execvp函数。
在Linux系统中,如果您在shell或终端上键入env
或printenv
,您将获得列表标准环境变量。
答案 5 :(得分:0)
在exec系列中,有些功能在功能和调用方式上略有不同:
在名称中包含字母p的函数(execvp
和execlp
)接受程序名称并在当前执行路径中按该名称搜索程序;必须为不包含p的函数指定要执行的程序的完整路径。
在名称中包含字母v的函数(execv
,execvp
和execve)接受新程序的参数列表作为以字符串形式的NULL终止指针数组。包含字母l(execl
,execlp
和。的函数
execle)使用C语言的varargs
机制接受参数列表。
在名称中包含字母e的函数(execve
和execle
)接受一个额外的参数,一个环境变量数组。参数应该是
以NULL结尾的字符串指针数组。每个字符串
应采用VARIABLE=value
。
答案 6 :(得分:0)
要回答问题的第一部分,特别是在Linux的上下文中,只有一个系统调用,并且 execve (不是 exec ) 。所谓的" exec家族的其余部分" ( execl , execle , execv , execve , execvp 等)是用于内核系统调用的所有GLIBC包装器,即 execve 。