当前位置:   article > 正文

Linux下的exec函数_linux execbyname

linux execbyname

在进程间的程序替换
用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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

运行结果:
[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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里写图片描述

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

这里写图片描述

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里写图片描述

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/181154?site
推荐阅读
相关标签
  

闽ICP备14008679号