【Linux】exec系列函数详细介绍
首先,exec
是 execute (意为:执行)
的缩写。
exec
系列函数
各个“后缀”的意思: l 为 list 可变参数列表、v 为 vector、p 为 PATH、e 为环境变量数组 envp
-
execl
:l 为 list 可变参数列表-
原型:
int execl(const char *path, const char *arg, ... /* (char *)NULL */);
-
功能:加载并执行指定的可执行文件,参数以变长参数列表的形式提供。
-
特点:参数列表以
NULL
结尾。 -
使用示例:
execl("/bin/echo", "echo", "Hello, world!", (char *)NULL);
-
-
execle
:l 为 list 可变参数列表,e 为环境变量数组 envp-
原型:
int execle(const char *path, const char *arg, ... /* (char *)NULL */, char * const envp[]);
-
功能:加载并执行指定的可执行文件,参数以变长参数列表的形式提供,并且可以指定环境变量数组。
-
特点:参数列表以
NULL
结尾,同时可以指定环境变量数组。 -
使用示例:
char *envp[] = {"HELLO=world", "USER=root", NULL}; execle("/bin/echo", "echo", "$HELLO", (char *)NULL, envp);
-
-
execlp
:l 为 list 可变参数列表,p 为 PATH-
原型:
int execlp(const char *file, const char *arg, ... /* (char *)NULL */);
-
功能:加载并执行指定的可执行文件,参数以变长参数列表的形式提供,并在
PATH
环境中查找可执行文件。 -
特点:参数列表以
NULL
结尾,使用PATH
环境变量查找可执行文件。 -
使用示例:
execlp("echo", "echo", "Hello, world!", (char *)NULL);
-
-
execv
:v 为 vector-
原型:
int execv(const char *path, char *const argv[]);
-
功能:加载并执行指定的可执行文件,参数以数组的形式提供。
-
特点:参数数组以
NULL
结尾。 -
使用示例:
char *args[] = {"/bin/echo", "Hello, world!", NULL}; execv("/bin/echo", args);
-
-
execve
:v 为 vector,e 为环境变量数组 envp-
原型:
int execve(const char *filename, char *const argv[], char *const envp[]);
-
功能:加载并执行指定的可执行文件,参数以数组的形式提供,并且可以指定环境变量数组。
-
特点:参数数组以
NULL
结尾,同时可以指定环境变量数组。 -
使用示例:
char *args[] = {"/bin/echo", "Hello, world!", NULL}; char *envp[] = {"HELLO=world", "USER=root", NULL}; execve("/bin/echo", args, envp);
-
-
execvp
:v 为 vector,p 为 PATH-
原型:
int execvp(const char *command, char *const argv[]);
-
功能:加载并执行指定的可执行文件,参数以数组的形式提供,并在
PATH
环境中查找可执行文件。 -
特点:参数数组以
NULL
结尾,使用PATH
环境变量查找可执行文件。 -
使用示例:
char *args[] = {"echo", "Hello, world!", NULL}; execvp("echo", args);
-
关于 execl
和 execv
:l 和 v
的区别
execl
和 execv
这两个实际上没什么区别
可以看作:一个使用 list 结构传参数,一个使用 vector 结构传参数
execlp("/bin/ls", "-l", "-a", nullptr);
execv("/bin/ls", argv); // char* argv[] = {"ls", -l", "-a", nullptr};
关于 execlp
和 execvp
: p
有什么用
execlp
和 execvp
函数的 p 表示的就是 PATH
环境变量的意思,带有 p 的这类函数不用写全路径,只需写可执行程序名即可:它们会在PATH
环境变量中查找可执行文件的位置,而不需要提供完整的路径。
例如:
execlp
:该函数不要求写全路径,只需要写命令名,程序名即可(他会自己到环境变量中找,没有就报错)
execlp("ls", "ls", "-l", "-a", nullptr);
该函数写了两次 ls
:内容一样,但表达的语义不同
第一个 ls
:表示要执行的程序名称的字符串,即该程序的名字,用于告诉系统可以在PATH
环境变量指定的目录中查找该文件
第二个 ls
:作为参数列表 argv数组
的第一个元素,因为在 exec
系列函数中,程序的名字需要作为参数列表的第一个元素。
关于 execve
和 execle
: e
有什么用
带 e
后缀说明:该函数支持显式传递环境变量数组。
main 函数接收到环境变量表,这张表就是该进程的环境变量表
若不显式传递,即不用这两个带 e
后缀函数,则子进程默认继承父进程的环境变量表
简单来说:给子进程显式传新环境变量表,则子进程就使用新表;否则,默认从父进程继承下来“初始”表
char *args[] = {"/bin/echo", "Hello, world!", NULL};
char *envp[] = {"HELLO=world", "USER=root", NULL};
execve("/bin/echo", args, envp); // 给子进程显式传新环境变量表 envp
exec 系列函数程序替换本身不会替换修改原进程中的 环境变量,但可以通过带 e
后缀的 exec 函数显式传递新表,并修改覆盖原表
一个进程的环境变量来源
1、默认继承:子进程默认继承父进程全部环境变量表
2、显式传递:父进程显示传递全新的环境变量表(自己定义自己传递),如 execle(…, …, env)
,子进程就用这张新表
3、新增环境变量:进程通过 int putenv(char *env_string);
,将环境变量 char *env_string
添加进当前环境变量表中,或修改表中已存在的环境变量
putenv
函数:用于修改当前进程的环境变量。
这个函数允许你在程序运行时动态地添加或更改环境变量。
- 在 shell 进程中调用,则修改 shell 的环境变量(即我们的命令行窗口的全局环境变量表)
- 在自己创建的进程中调用,则修改自己进程的环境变量
exec 系列函数都是库函数吗?
实际上,只有 execve 函数是真正的系统调用函数
其他的函数都是C语言库函数,内部都封装调用了 execve 函数,这几种函数只有传参方式的差别,就是为了满足不同的应用场景。
以C标准库的 execl
函数为为例,其底层的运行原理为
1、处理变长参数列表,分配内存并存储在参数列表 argv 中
2、调用 execve 函数
3、释放内存,如 argv
我们在 shell
中,通过 man
命令查询手册
原文地址:https://blog.csdn.net/2301_79499548/article/details/143084610
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!