当前位置: 首页 > article >正文

【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数

 🎁个人主页:我们的五年

🔍系列专栏:Linux课程学习 

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

替换原理:

替换函数:

命名理解:

命令:

6个exe函数 

1.execl函数

函数原型:

函数解释:

实例:

2.execv函数

函数原型:

函数解释:

示例:

3.execlp和execvp

函数原型:

4.execle和execve函数:

execvpe函数:

函数原型:

函数解释:

总结:


 

推荐书籍:

《深入理解计算机系统》《程序员的自我修养》

1.理解子进程去调用替换函数,达到我们想要的目的。shell命令行也是这样进行处理,我们每次操作的命令,都是fork()创建子进程,然后让子进程调用exe函数进行程序替换,去执行我们想要的程序。比如ls……这些都是一些执行对应程序。

2.进程替换没有创建新进程,所以调用替换函数的进程的pid不会发生变化。

3.程序替换函数只要成功,就会会发生代码替换,就不会有返回值。如果有返回值,就表示程序替换失败。

替换原理:

当一个程序调用exe类型的函数时,这个进程的用户空间代码和数据完全被新进程替换。

从新程序的启动历程开始执行。(C/C++从mian函数开始执行)

exe程序替换函数一般是子进程进行调用。

调用exe类型的函数不会创建新进程,调用exe函数的进程pid不会改变。

替换函数:

程序替换函数以exe开头,所以统称为exe函数。

这些函数包含在头文件:

#include <unistd.h>

命名理解:

●l(list):表示参数采用链表。

●v(vector):采用数组。

●p(PATH):有p表示自动搜索环境变量PATH。

●e(env):表示自己维护环境变量。

命令:

在/usr/bin中放置的就是命令的可执行文件。

6个exe函数 

1.execl函数

函数原型:

int execl(const char* path,const char* arg,...);

函数解释:

1.三个点表示可变参数列表,可以传多个参数。

2.path表示要替换程序的路径。(在哪里)

3.后面的arg表示什么样的命令执行。(怎么执行)


实例:

--color表示带颜色显式,这里有两个-。

也可以执行自己的路径,执行自己的可执行程序。

#include <unistd.h>
#include <iostream>
 
int main()
{
    int a=execl("/usr/bin/ls","ls","-l","-a","--color",nullptr);
                                                                                                    
    //如果打印了a的值就表示替换失败
    std::cout<<a<<std::endl;
    return 0;
}

2.execv函数

函数原型:

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

函数解释:

1.把这个和1号函数进行比较,唯一的区别就是后面不一样:

execv传递的是一个char* const的数组,而execl传递的是一个个const char*。

v像vector,表示数组。l像list表示的链表,链表就是分别传参。

2.这两个函数没有本质区别,底层都是调用execve。他们就只有传参的不一样,execl调用execve后,传递的每个const char*会变成一个char*数组。

3.后面的几个函数都只有参数不同,底层都调用execve。设计这么多函数是为了满足不同场景的需求,有时候就是要一个一个传参,有时候就有char*数组。

示例:

3.execlp和execvp

函数原型:

int execlp(const char* file,const char* arg,...);

int execlp(const char* file,char* const argv[]);

这两个函数都是带p的,就不要写路径。

 #include <unistd.h>
 #include <iostream>
 
 int main()
 {
     //int a=execl("/usr/bin/ls","ls","-l","-a","--color",nullptr); 
     //int a=execl("./myprocess","./myprocess",nullptr);
 
     pid_t id=fork();
 
     if(id==0)
     {

         char* const argv[]={
             (char*)"ls",
             (char*)"-l",
             (char*)"-a",
             (char*)"--color",
             nullptr                                                                                                                                                                                                
         };
 
         //int a=execv("/bin/ls",argvs);
 
         // int a=execlp("ls","ls","-l","-a","--color",nullptr);
 
         int a=execvp("ls",argv);
 
         //如果打印了a的值就表示替换失败
         std::cout<<a<<std::endl;
         exit(1);
     }

     pid_t pid=waitpid(id,nullptr,0);
 
     if(pid>0)
     {
         std::cout<<"等待进程成功!"<<std::endl;
     }
 
     else if(pid<0)
     {
         std::cout<<"等待进程失败!"<<std::endl;
     }
     return 0;
}

4.execle和execve函数:

有e的是要进行自己进行组装环境变量的。

带e的,需要⾃⼰组装环境变量 
execle("ps", "ps", "-ef", NULL, envp);
带e的,需要自己组装函数变量
execve("/bin/ps",argv,envp);

execvpe函数:

函数原型:

int execvpe(const char* file,char* const argv[],char* const env[]);

函数解释:

1.env是我们传递的全新的环境变量。对于env我们可以传递父进程的环境变量,也可以在父进程的环境变量上新增。

2.刚刚开始的bash进程就要传递自己写的环境变量。自己写的环境变量,自己定义,自己传递。

3.如何新增环境变量:

getenv:获取环境变量。

#include <stdlib.h>

char *getenv(const char *name);

putenv:新增环境变量。

#include <stdlib.h>

int putenv(char *string);

总结:

实际上,只有execve才是真正的系统调用,其他的函数都是调用execve。所以execve在man的手册2,其他函数在手册3。


http://www.kler.cn/a/410301.html

相关文章:

  • 优化Docker镜像:提升部署效率与降低资源消耗
  • 累积局部效应 (ALE) 图分析记录
  • 【Rust练习】23.生命周期
  • Spring 框架七大模块(Java EE 学习笔记03)
  • IT服务团队建设与管理
  • Android 不同情况下使用 runOnUiThread
  • 搜维尔科技:多画面显示3D系统解决方案,数据孪生可视化大屏3D展示技术
  • oracle RMAN同机迁移数据库从ASM至文件系统(同机)
  • Stable Diffusion初步见解(三):扩散模型
  • 网络安全简单入门与扫描
  • 利用Python爬虫获取商品评论:技术与实践
  • 机器学习-41-对ML的思考之从开普勒的研究过程看科学范式
  • 全面解析多种mfc140u.dll丢失的解决方法,五种方法详细解决
  • 大数据-233 离线数仓 - 留存会员 需求、创建与加载DWS 层、ADS 层 与 小结
  • 【代码pycharm】动手学深度学习v2-08 线性回归 + 基础优化算法
  • 软件工程第13章小测
  • 【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
  • Docker 的存储驱动及其优缺点
  • 超高流量多级缓存架构设计!
  • 配置Springboot+vue项目在ubuntu20.04
  • Vue实训---1-创建Vue3项目
  • docker离线安装linux部分问题整理
  • 电话机器人的未来发展前景,未来发展趋势怎么样?
  • ThingsBoard规则链节点:Azure IoT Hub 节点详解
  • ubuntu 安装 conda
  • ajax基础