Linux----exec系列家族函数(进程程序替换)

这篇博客介绍了Linux中的exec系列函数,包括execl、execlp、execle、execv、execvp和execve,它们用于执行新的程序并替换当前进程。文章强调了这些函数的使用规则,如path与file的区别、参数列表l与v的差异以及环境变量e的应用,并通过代码示例帮助读者理解各个函数的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       其实有六种以exec开头的函数,统称exec函数: 

 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[], char *const envp[]); 

 以上函数包含在头文件#include <unistd.h>


注意:这些函数的返回值与以往的有所不同。

          如果调用成功则加载新的程序从启动代码开始执行,不再返回,

         如果调用出错则 返回-1,

         所以exec函数只有出错的返回值而没有成功的返回值。

如何记忆以上的函数呢?下面对函数及形参做以说明。

 1.不带字母p(path)的函数:第一个参数(path)必须是程序的相对路径或绝对路径。

                               例如:“/bin/ls”而不是“ls”。

   对于带字母p的函数:第一个参数(file)是程序名。

                                例如:“ls”

 2.带有字母l(list)的函数:要求将新程序的每个命令行参数都当做一个参数传给它。其命令行参数是可变的,最后    一个可变参数必须以NULL结尾。

   带有字母v(vector)的函数:先要构造一个指向各参数的指针数组。然后将该数组的首地址当做参数传给它。数      组中的最后一个指针是NULL。

   注意:l,v是不共存的。二者只能选其一

  3.带有字母e(environment)的函数:可以把一份新的环境变量表传给它。首先要构造一个指针数组,然后将数组穿进  去。数组中的最后一个指针是NULL。

  exec函数组其他5个函数底层都是调用execve函数的。

            

  execl函数举例:(以下测试代码都是在centos下测试的)

  结果为:

  

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7 
  8  pid_t id=fork();
  9  if(id==0)//child
 10  {
 11   printf("this is child.pid:%d   ppid:%d\n",getpid(),getppid());
 12   sleep(3);
 13   execl("/bin/ls","ls","-a","-i","-n",NULL);
 14   printf("child end;\n");
 15  }
 16  else
 17  {
 18   
 19   printf("this is father.pid:%d   ppid:%d\n",getpid(),getppid());
 20   pid_t ret=waitpid(id,NULL,0);
 21   if(ret>0)
 22       printf("wait success!ret:%d\n",ret);
 23  }
 24 
 25 
 26 }
 结果为:

   

execlp函数测试:

 1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7 
  8  pid_t id=fork();
  9  if(id==0)//child
 10  {
 11   printf("this is child.pid:%d   ppid:%d\n",getpid(),getppid());
 12
 13   execlp("ls","ls","-a","-i","-n",NULL);
 14   printf("child end;\n");
 15  }
 16  else
 17  {
 18 
 19   printf("this is father.pid:%d   ppid:%d\n",getpid(),getppid());
 20   pid_t ret=waitpid(id,NULL,0);
 21   if(ret>0)
 22       printf("wait success!ret:%d\n",ret);
 23  }
 24 
 25 
 26 }

结果为:

          

execv函数:

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7 
  8  pid_t id=fork();
  9  if(id==0)//child
 10  {
 11   printf("this is child.pid:%d   ppid:%d\n",getpid(),getppid());
 14   char *_argv[]={"ls","-a","-i","-n",NULL};
 15   execv("/bin/ls",_argv);
 16   printf("child end;\n");
 17  }
 18  else
 19  {
 20 
 21   printf("this is father.pid:%d   ppid:%d\n",getpid(),getppid());
 22   pid_t ret=waitpid(id,NULL,0);
 23   if(ret>0)
 24       printf("wait success!ret:%d\n",ret);
 25  }
 26 
 27 
 28 }
结果和上面两个是一样的,就不截屏了。

execle函数:

先创建一个mybin.c

其内容为:

 

  1 #include <unistd.h>
  2 #include <stdio.h>
  3 extern char** environ;
  4 int main(void)
  5 {
  6     printf("hello pid=%d\n", getpid());
  7     int i;
  8     for (i=0; environ[i]!=NULL; ++i)
  9     {
 10         printf("%s\n", environ[i]);  
 11     } 
 12     return 0;
 13 }


myexec.c文件中:

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7 
  8  pid_t id=fork();
  9  if(id==0)//child
 10  {
 11   printf("this is child.pid:%d   ppid:%d\n",getpid(),getppid());
 16   char* _env[]={"MYENV=/a/b/c",NULL};
 17   sleep(5);
 18   execle("./mybin","mybin",NULL,_env);
 19   printf("child end;\n");
 20  }
 21  else
 22  {
 23 
 24   printf("this is father.pid:%d   ppid:%d\n",getpid(),getppid());
 25   pid_t ret=waitpid(id,NULL,0);
 26   if(ret>0)
 27       printf("wait success!ret:%d\n",ret);
 28  }
结果为:

             



execve函数:

先创建一个文件mybin.c,内容同上。

myexec.c内容:

 1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7  pid_t id=fork();
  8  if(id==0)//child
  9  {
 10   printf("this is child.pid:%d   ppid:%d\n",getpid(),getppid());
 15   char* _argv[]={"mybin",NULL};
 16   char* _env[]={"MYENV=/a/b/c",NULL};
 18   execve("./mybin",_argv,_env);
 19   printf("child end;\n");
 20  }
 21  else
 22  {
 23    printf("this is father.pid:%d   ppid:%d\n",getpid(),getppid());
 24   pid_t ret=waitpid(id,NULL,0);
 25   if(ret>0)
 26       printf("wait success!ret:%d\n",ret);
 27  }    
 28 }
结果如下:

          

 









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值