Linux下exec函数族比如execve等函数的基本使用

exec族的任一函数都不创建一个新的进程,而是在调用进程里面去执行新的程序。所以进程id不变,还是调用exec函数前的进程id,但是用户空间的代码和数据都更新了,变为新程序的代码和数据了。 

extern char **environ; //全局环境变量,导入到本文件即可直接使用

1. int execl(const char *path, const char *arg, ...);

功能:通过路径+文件名来加载一个进程;path文件路径;arg文件名称;...可变参数,至少一个NULL

附:l即list 

返回值:成功的情况下是没有返回的,失败时返回-1 。

举例说明:

execl("/bin/ls", "ls", "-a", "-l", NULL); //path绝对路径,如/bin/ls;文件名称ls;后面三个可变参数,最后必须以NULL结束

2. int execlp(const char *file, const char *arg, ...);

功能:借助PATH环境变量加载一个进程,file要加载的程序的名称

附:l即list;p即path 

该函数需要配合PATH环境变量来使用,当PATH中所有目录搜索后没有参数file,则出错返回。

该函数通常用来调用系统程序。如:ls、cp、cat等命令。 

返回值:成功的情况下是没有返回的,失败时返回-1 。

举例说明:

execlp("ls", "ls", "-a", "-l", NULL); //第一个ls是指查看PATH环境变量里的ls;第二个ls是名称文件;后面是可变参数,NULL结束

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

功能:加载指定路径的程序,并为新程序复制最后一个环境变量

  附:l即list;e即environment

举例说明:

char* envp[] = {NULL};

execlp("ls", "ls", "-a", "-l", NULL, envp);

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

功能:加载指定路径的程序 

附:v即vector,命令行参数列表

举例说明:

char* argv[] = {"ls", "-a", "-l", NULL}; 

execl("/bin/ls",argv);

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

功能:加载path环境变量里的名称为file的程序 

附:v即命令行参数列表,p即path 

int main(int argc, char *argv[]) {

pid_t pid = fork();

if (pid == 0) { //子进程里加载ls程序

char* argvv[] = {"ls", "-a", "-l", NULL};

execvp("ls", argvv);

perror("execlp");   exit(1); //只有execl函数执行失败的情况下才有机会执行这两句代码,执行的成功话就有去无回了。

} else if (pid > 0) {

sleep(1); printf("parent\n");

}

return 0;

}

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

功能:加载指定的程序;filename必须是一个可执行程序或者一个以#! interpreter [optional-arg] 开始的脚本。

上面的五个exec函数是库函数,这个是系统函数;上面的五个exec函数最终都是调用这个函数实现的。 

 

总结:exec族函数的规律

exec函数一旦调用成功就有去无回了,去执行新的程序去了。只有失败时才有返回,返回值为-1。所以我们直接在exec函数调用后直接调用perror()和exit(),不需要if判断,因为失败的情况才会执行。

函数名的意义的理解: 

l (list) 命令行参数列表

p (path) 环境变量,环境变量搜素文件名称file

v (vector) 命令行参数数组

e (environment) 环境变量数组,给新加载程序设置指定的环境变量

函数的相似性: 

execlp——>execvp 

    |  

execl  ——>execv

    | 

execle——>execve

从左往右,可变参数转为以NULL结尾的指针数组;从左往右, 从上往下,最后归根结底都是调用execve函数实现的。

posted @   yongfengnice  阅读(2511)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示