Linux下的exec函数

在进程间的程序替换
用fork创建子进程后执行的是和父进程相同的程序(但有可能执⾏行不同的代码分⽀支),
子进程往往要调用一种exec函数以执⾏行另⼀一个程序。
当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。
调用exec并后该进程的id并未改变。不创建新进程,所以调用exec前后该进程的id并未改变。因此在task_struct中的其他信息并没有发生改变

这里写图片描述

其实有六种以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[], char *const envp[]); 

1、使用execl:
带有字母l(表⽰示list)的exec函数要求将新程序的每个命令行参数都当作一个参数传给 它,命令行 参数的个数是可变的,因此函数原型中有…,…中的最后⼀一个可变参数应该是 NULL, 起sentinel的作用

#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{

     pid_t id=fork();
     if(id==0)
     {
          printf("child start!\n");
          sleep(3);
          execl("/bin/ls","ls","-a","-l","-n","-i",NULL);
          printf("child end!\n");    
     }
     else
     {
          pid_t ret=wait(NULL);
          if(ret>0)
          {
               printf("wait child success!\n");
          }
     }
     return 0;
}

运行结果:
[admin@localhost linux8]$ ./wait
child start!
total 24
1054015 drwxrwxr-x. 2 500 500 4096 May 10 01:18 .
1053939 drwxrwxr-x. 7 500 500 4096 May 9 20:39 ..
1054019 -rw-rw-r–. 1 500 500 65 May 9 20:41 makefile
1054018 -rwxrwxr-x. 1 500 500 5224 May 10 01:18 wait
1054021 -rw-rw-r–. 1 500 500 2099 May 10 01:18 wait.c
wait child success!
在子进程中进行了程序的替换也就是ls程序的代码和数据替换了子进程的代码和数据

2、使用int execlp(const char *file, const char *arg, …);
不用加具体路径
不带字母p(表⽰示path)的exec函数 第⼀一个参数必须是程序的相对路径或绝对路径,例如 “/bin/ls”或”./a.out”,⽽而不能 是”ls”或”a.out”。对于带字母p的函数: 如果参数中包含/,则 将其视为路径名。 否则视为不带路径的程序名,在PATH环境变量的⽬目录列表中搜索这 个程序

int main()
{

     pid_t id=fork();
     if(id==0)
     {
          printf("child start!\n");
          sleep(3);
          execlp("ls","ls","-a","-l","-n","-i",NULL);
          printf("child end!\n");    
     }
     else
     {
          pid_t ret=wait(NULL);
          if(ret>0)
          {
               printf("wait child success!\n");
          }
     }
     return 0;
}

这里写图片描述

3、int execv(const char *path, char *const argv[]);

带有字母v(表⽰示vector)的函数,则应该先构造⼀一个指向各参数的指针数 组,然后将该数 组的⾸首地址当作参数传给它,数组中的最后⼀一个指针也应该是NULL,就像main函数 的 argv参数或者环境变量表⼀样。

int main()
{

     pid_t id=fork();
     if(id==0)
     {
          printf("child start!\n");
          sleep(3);
          char*_argv[]={"ls","-a","-l","-n","-i",NULL};
          execv("/bin/ls",_argv);
          printf("child end!\n");    
     }
     else
     {
          pid_t ret=wait(NULL);
          if(ret>0)
          {
               printf("wait child success!\n");
          }
     }
     return 0;
}

这里写图片描述

4、int execvp(const char *file, char *const argv[]);

带有字母v(表⽰示vector)的函数,则应该先构造⼀一个指向各参数的指针数 组,然后将该数 组的⾸首地址当作参数传给它,数组中的最后⼀一个指针也应该是NULL,就像main函数 的 argv参数或者环境变量表⼀一样。
不带字母p(表⽰示path)的exec函数 第⼀一个参数必须是程序的相对路径或绝对路径,例如 “/bin/ls”或”./a.out”,⽽而不能 是”ls”或”a.out”。对于带字母p的函数: 如果参数中包含/,则 将其视为路径名。 否则视为不带路径的程序名,在PATH环境变量的⽬目录列表中搜索这 个程序。

int main()
{

     pid_t id=fork();
     if(id==0)
     {
          printf("child start!\n");
          sleep(3);
          char*_argv[]={"ls","-a","-l","-n","-i",NULL};
          execvp("ls",_argv);
          printf("child end!\n");    
     }
     else
     {
          pid_t ret=wait(NULL);
          if(ret>0)
          {
               printf("wait child success!\n");
          }
     }
     return 0;
}

这里写图片描述

5、int execle(const char *path, const char *arg, …, char *const envp[]);

对于以e(表⽰示environment)结尾的exec函数,可以把一份新的环境变量表传给它,其他 exec函数 仍使⽤用当前的环境变量表执行新程序

#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
   pid_t id=fork();
   if(id==0)
   {
        printf("child start\n");
        char* envTable[]={"MYENV=/hello/word/aa/bb/cc/xx/yy",NULL};
       execle("./myenv","myenv",NULL,envTable);
   }
    else
     {
     pid_t ret=wait(NULL);
     printf("father end \n");
}
return 0;
}

#include<stdio.h>
int main()
{
     printf("MYENV is %s\n",getenv("MYENV"));
     return 0;
}

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值