exec替换进程印象
在进程的创建上Unix采用了一个独特的方法,它将进程创建与加载一个新进程映象分离。这样的好处是有更多的余地对两种操作进行管理。
当我们创建了一个进程之后,通常将子进程替换成新的进程映象,这可以用exec系列的函数来进行。当然,exec系列的函数也可以将当前进程替换掉。
例如:在shell命令行执行ps命令,实际上是shell进程调用fork复制一个新的子进程,在利用exec系统调用将新产生的子进程完全替换成ps进程
exec关联的函数族
包含头文件<unistd.h>
用exec函数可以把当前进程替换为一个新进程,且新进程与原进程有相同的PID。exec名下是由多个关联函数组成的一个完整系列,头文件<unistd.h>
原型
/*
int execl(const char *path, const char *arg, ..., (char *) NULL );
int execlp(const char *file, const char *arg, ..., (char *) NULL);
int execle(const char *path, const char *arg, ..., (char *) NULL, char * const envp[]);
---------------------------------------------------------
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
//只有execvpe是系统调用
*/
以execlp、execvp、和execle讲解
path参数表示你要启动程序的名称包括路径名
arg参数表示启动程序所带的参数
返回值:成功返回0,失败返回-1
execl,execlp,execle(都带“l”)的参数个数是可变的,参数以一个空指针结束。
execv和execvp的第二个参数是一个字符串数组,新程序在启动时会把在argv数组中给定的参数传递到main
这些函数通常都是用execve实现的,这是一种约定俗成的做法,并不是非这样不可。
名字最后一个字母是“p”的函数会搜索PATH环境变量去查找新程序的可执行文件。如果可执行文件不在PATH定义的路径上,就必须把包括子目录在内的绝对文件名做为一个参数传递给这些函数
总结:l代表可变参数列表,p代表在path环境变量中搜索file文件。envp代表环境变量。
#if 1
int test()
{
pid_t pid;
printf("getpid():%d\n", getpid());
execle("./hello", NULL, NULL);
printf("end.....\n");
return 0;
}
hzmct@U-64:/study/linuxtest/day01/03execv$ ./dm01_exec
getpid():5246
getpid():5246
#endif
/*
execlp要执行的可执行程序,必须能够在环境变量中找到
*/
int test()
{
pid_t pid;
printf("主进程getpid():%d\n", getpid());
//执行命令 echo $PATH which ls
//int execlp(const char *file, const char *arg, ..., (char *) NULL);
//execlp("ls", "ls", "-al", NULL);
execlp("./hello", "ls", "-al", NULL);
printf("hello\n");
return 0;
}
#if 1
int test()
{
pid_t pid;
printf("getpid():%d\n", getpid());
char * const envp[] = {"aaa=111", "bbb=2222", NULL};
printf("hello\n");
return 0;
}
#endif
/*
1、带 p 的exec函数:execlp,execvp,表示第一个参数path不用输入完整路径,
只有给出命令名即可,它会在环境变量PATH当中查找命令
2、不带 l 的exec函数:execv,execvp表示命令所需的参数以char *arg[]形式
给出且arg最后一个元素必须是NULL
3、带e的exec函数:execle表示,将环境变量传递给需要替换的进程
*/
int test()
{
printf("entering main process---\n");
int ret;
char *argv[] = {"ls","-l",NULL};
ret = execvp("ls",argv);
if(ret == -1)
perror("execl error");
printf("exiting main process ----\n");
return 0;
}