一、替换原理
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,改进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
二、替换函数
有六种以exec开头的函数,统称为exec函数:
#include<unistd.h>
int execl(const char* path,const char* arg, ...);
int execlp(const char* file,const char* arg, ...);
int execle(const char* path,const char* arg, ...,char* const envp[]);
int execv(const char* path,char* const argv[]);
int execvp(const char* file,char* const argv[]);
int execve(const char* path,char* const argv[],const char* envp[]);
三、函数解释
1、path为指定路径名。file则不用指定路径名,默认会在PATH环境变量指定的路径下找。
2、arg参数表示启动程序所带的参数,一般第一个参数为要执行命令名,不是带路径且arg必须以NULL结束。
3、这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
4、如果调用出错返回-1。
5、exec函数只有出错的返回值而没有成功的返回值。
四、应用实例
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("progress start\n");
int ret=execl("/bin/ls","ls","-l","-a",NULL);
//int ret=execlp("ls","ls","-l","-a",NULL);
if(ret<0)
{
perror("execl error");
return 0;
}
printf("progress end\n");
return 0;
}
运行结果:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("progress start\n");
char* env[]={0};
int ret=execle("/bin/ls","ls","-l","-a",NULL,env);
if(ret<0)
{
perror("execle error");
return 0;
}
printf("progress end\n");
return 0;
}
运行结果:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("progress start\n");
char* argv[]={"ls","-l","-a"};
int ret=execv("/bin/ls",argv);
//int ret=execvp("ls",argv);
if(ret<0)
{
perror("execv error");
return 0;
}
printf("progress end\n");
return 0;
}
运行结果:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf("progress start\n");
char* argv[]={"ls","-l","-a"};
char* env[]={0};
int ret=execve("/bin/ls",argv,env);
if(ret<0)
{
perror("execve error");
return 0;
}
printf("progress end\n");
return 0;
}
运行结果:
五、命名理解
带 l (list):参数采用列表
带 v (vector):参数用数组
带 p (path):自动搜索环境变量PATH
带 e (env):需要自己维护环境变量
函数名 | 参数格式 | 是否带路径 | 是否使用当前环境变量 |
execl | 列表 | 不是 | 是 |
execlp | 列表 | 是 | 是 |
execle | 列表 | 不是 | 不是,需自己设置 |
execv | 数组 | 不是 | 是 |
execvp | 数组 | 是 | 是 |
execve | 数组 | 不是 | 不是,需自己设置 |