定义
exec函数族提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的进程替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行的脚本文件
exec函数的原型如下:
int execl(const char * path,const char * arg,…);
int execle(const char * path,const char * arg,char * const envp[]);
int execlp(const char * file,const char * arg,…);
int execv(const char * path,char * const argv[]);
int execve(const char * path,char * const argv[],char * const envp[]);
int execvp(const char * file,char * const argv[]);
参数说明:
path:要执行的程序路径。可以是绝对路径或者是相对路径。在execv、execve、execl和execle这4个函数中,使用带路径名的文件名作为参数。
file:要执行的程序名称。如果该参数中包含“/”字符,则视为路径名直接执行;否则视为单独的文件名,系统将根据PATH环境变量指定的路径顺序搜索指定的文件。
argv:命令行参数的矢量数组。
envp:带有该参数的exec函数可以在调用时指定一个环境变量数组。其他不带该参数的exec函数则使用调用进程的环境变量。
arg:程序的第0个参数,即程序名自身。相当于argv[O]。
…:命令行参数列表。调用相应程序时有多少命令行参数,就需要有多少个输入参数项。注意:在使用此类函数时,在所有命令行参数的最后应该增加一个空的参数项(NULL),表明命令行参数结束。
返回值:一1表明调用exec失败,无返回表明调用成功。
execl函数
我们要让一段代码(A)在执行过程中去执行另一个程序(B)
代码B
#include <stdio.h>
int main(int argc,char **argv)
{
int i;
for(i=0;i<argc;i++){
printf("argv[%d]:%s\n",i+1,argv[i]);
}
return 0;
}
代码A
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("使用execl之前\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
if(execl("./echoarg","exhoarg","abc",NULL) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用execl之后\n");//如果调用成功则不会打印这条
return 0;
}
结果
同时我们也可利用execl函数执行linux终端的指令,类似ls、ls -l等等指令
ls
首先我么你要找到ls 程序的路径
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("使用execl之前\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
if(execl("/bin/ls","ls",NULL,NULL) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用execl之后\n");//如果调用成功则不会打印这条
return 0;
}
ls -l
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("使用execl之前\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
if(execl("/bin/ls","ls","-l",NULL) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用execl之后\n");//如果调用成功则不会打印这条
return 0;
}
如果我们想获得系统的时间呢,也可以用execl函数
同样我们要获得date的程序路径
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("使用execl之前\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
if(execl("/bin/date","date",NULL,NULL) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用execl之后\n");//如果调用成功则不会打印这条
return 0;
}
当我们使用execl函数时就必须获得要被执行程序的绝对路径,不然就会报错,遮掩过就很繁琐每次都得去找,然而execlp很好的帮我们解决了这个问题
execlp函数
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("查看系统时间\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
if(execlp("date","date",NULL,NULL) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用失败\n");//如果调用成功则不会打印这条
return 0;
}
execlp能通过环境变量PATH查找到可执行程序date
execvp函数
这个就更加简单
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("查看系统时间\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
char *argv[]={"date",NULL,NULL};
if(execvp("date",argv) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用失败\n");//如果调用成功则不会打印这条
return 0;
}
execv函数
这个就更之前一眼更得加个绝对路径
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("查看系统时间\n");
//int execl(const char *path, const char *arg, ... /* (char *) NULL */);
char *argv[]={"date",NULL,NULL};
if(execv("/bin/date",argv) == -1){//如果返回值是-1则调用失败
printf("调用execl失败\n");
perror("why:");
}
printf("调用失败\n");//如果调用成功则不会打印这条
return 0;
}