Linux程序替换(exec)

程序的替换

在有些场景中我们需要创建一个进程,让该进程来帮我们完成某项工作,比如Linux中的shell,shell就是一个进程,他通过不断创建子进程,通过让子进程来帮我们执行程序。

程序替换的原理

Linux程序替换(exec)_第1张图片

程序替换只是将替换的进程加载到内存中,然后修改当前进程的映射信息,完成替换,程序替换并不会创建新的进程。

替换函数

在linux中程序替换是通过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 execvpe(const char *file, char *const argv[],char *const envp[]);
返回值:函数仅在发生错误时返回,返回值为-1;

exec命名规则

exec函数族都是以exec开头,后面的每个字母都有不同的含义

  • l(list):表示参数采用列表的形式(一一列出来)。
  • v(vector):表示参数参数采用数组的形式。
  • p(path):会在环境变量PATH中进行找需要替换的程序(不需要填写程序的路径)。
  • e(env):可以传入自己的环境变量。

execl

execl("/usr/bin/ls","ls","-al",NULL);    
  • 第一个参数为替换程序的路径,因为该函数不带P,所以就需要填写替换程序的路径。
  • 第二个参数为如何执行这个程序,也就是在命令行上你是怎么样运行它的,将参数一一列举出来,在最后写一个NULL,表示结尾。

execlp

execlp("ls","ls","-al",NULL);    

这个函数和上面的execl唯一的区别就是这个函数多一个p,就表示当前函数进行替换时,替换的程序如果在PATH环境变量中,就可以不用在填写路径。

execv

     char* argv[]={"ls","-al",NULL};
     execv("/usr/bin/ls",argv);    

v表示参数以数组的形式进行传参,所以我们定义了一个指针数组,数组中存放的就是一条一条的命令,最后也是也NULL结尾。

execvp

	char* argv[]={"ls","-al",NULL};	
	execvp("ls",argv);

带V和P说明了,可以不用传文件的路径,参数以列表的形式。

execle

char* const env[]={"hello","world",NULL};
execle("a.out","ls","-al",NULL,env);   

e表示我们可以给替换的程序传入环境变量,这个我们就传入一个自定义的环境变量,同样环境变量最后也是也NULL结尾。

#include 
int main()
{
    extern char** environ;
    for(int i = 0;environ[i];i++)
    {
        printf("%s\n",environ[i]);
    }
    return 0;
}
#include 
#include 
int main()
{
    char* const env[]={"hello","world",NULL};
    execle("a.out","ls","-al",NULL,env);
    //这里要替换的a.out和当前程序在一个目录下,所以没有写全路径。
    return 0;
}

在上面的代码中我们给替换的程序传入一个环境变量,而替换的那个程序的工作就是打印当前进程的环境变量。

Linux程序替换(exec)_第2张图片

execve

  execve("a.out",argv,env);

同样的我们可以使用数组的形式来传递参数。

Linux程序替换(exec)_第3张图片

execve

在Linux中上面的6个函数只有execve是系统调用,其他的5个函数都是库函数,他们对应的关系如下

Linux程序替换(exec)_第4张图片

你可能感兴趣的:(Linux,c++,开发语言,后端)