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

【Linux】进程替换、命令行参数及环境变量(超详解)

目录

进程替换

替换函数的含义

命令行参数

环境变量

PATH


进程替换

我们先看代码:

  1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5     printf("process...begin!\n");6 7     execl("/usr/bin/ls","ls","-a","-l",NULL);8 9     printf("process...end!\n");10     return 0;11 }

运行结果:

 

通过运行结果,我们会发现:

 printf("process...end!\n");并没有被执行;

这是为什么?

我们先来看一下exec函数:

还有一个:int execve(const char *path, char *const argv[], char *const envp[]);

exec函数其实就是替换函数,图像表示:

        以上述代码为例:execl("/usr/bin/ls","ls","-a","-l",NULL);就是将磁盘中的有一段程序的代码和数据替换掉父进程在内存中的代码和数据;exec*执行完毕后,后续的代码不见了,是因为被exec*替换了,所以不会执行exec*后面的代码,简单来说:被替换后后面代码已经找不到了,自然不会被执行;

        这个替换,本质就是这个程序被加载到内存了(exec*函数类似于一种Linux上的加载函数);

那我们非要让后面的代码可以执行,要怎么做呢?

        很简单,父进程中exec*函数后的代码无法执行是因为exec*函数的替换,把后续代码给替代了,找不到后续代码;那我们让后续代码可以找到不就可以了?怎么让它可以找到-------->fork创建子进程,在子进程中执行exec*函数,这就是用的我们之前提到的写实拷贝(让子进程自己去替换,父进程的代码和数据不受影响);

  1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 int main()5 {6     printf("process...begin!\n");7 8     pid_t id =fork();9     if(id==0)10     {11         execl("/usr/bin/ls","ls","-a","-l",NULL);12         exit(1);13     }14     //父进程15     sleep(5);16     printf("process...end!\n");17     return 0;18 }

这样父进程后续代码就可以被执行了;

原理是什么呢?

一开始,子进程完全的父进程的拷贝(页表指向是红色箭头),后面由于exec*函数替换,因为替换的不仅仅是数据,连代码也替换了,这时OS就是进行写时拷贝,把代码和数据都复制了一份(绿色和蓝色箭头的指向);父进程代码和数据仍然存在;

替换函数的含义

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

这个l指的是list 列表,path就是要执行程序的路径,arg:在命令行中怎么执行,这个就怎么写:

例如:ls -a ---->"ls","-a",即可;最后一个参数必须为NULL;

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

这个v指的是vector,path是路径,argv:就是把命令放到argv里面;

例如:

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

用户可以不传要执行文件的路径,但是要传文件名,直接告诉exec*函数,我要执行谁;

这里的p:查找这个程序,系统会在环境变量PATH进行查找;

例如:

(4)int execle(const char *path, const char *arg, ...,char *const envp[]);

这里的e:environment:环境变量; envp[]:整体替换所有的环境变量;

例如:

当然,除了可以替换系统命令,也可以替换我们自己写的程序:

先写一个程序:test.c,然后执行:

使用: 

即可:

运行结果:

命令行参数

我们发现在main函数中可带参数,也可以不带参数;

带参数:

这个参数有什么用呢?

我们看下面的代码,将argv打印出来:

运行结果:

根据运行结果我们可以理解:命令行参数本质是交给我们程序的不同选型,用来定制不同的程序功能,命令中会携带很多选项;

例如:ls -a;

           ls -l;等

环境变量

        在Linux中,存在一些全局的设置,表明,告诉命令行解释器应该取哪些路径下去寻找可执行程序;

PATH

PATH:环境变量;

$PATH:打印环境变量内存;

系统中很多的配置,在登录Linux系统的时候,已经加载到bash进程中(内存);

我们发现ls命令:并不需要./,但是我们自己写的程序,比如myprocess,运行时却要./myprocess才可以运行,这是为什么?

我们只需要将我们的程序配置到环境变量中即可;

那怎么配置呢?

/PATH=$PATH:路径;

例如:

        PATH=$PATH:home/sxh/111/lesson06;

因为我们配置的这个PATH是在内存中,重启后,PATH就会复原;

当然,除了PATH,还有其他的环境变量,比如:HOME/SHELL/HISISIZE/PWD等;

env:查看所有环境变量

echo $xxx:查看某一个环境变量

export name=value:设置环境变量

unset name:取消环境变量

怎么打印环境变量?

运行结果:

注意:环境变量默认是可以被子进程拿到的;

http://www.lryc.cn/news/455142.html

相关文章:

  • MySQL事务日志—redo日志介绍
  • 告别音乐小白!字节跳动AI音乐创作工具,让你一键变作曲家!
  • 空心正方形图案
  • 【EXCEL数据处理】000020 案例 保姆级教程,附多个操作案例。EXCEL使用表格。
  • 虾皮Shopee大数据面试题及参考答案
  • 重学SpringBoot3-集成Redis(六)之消息队列
  • LeetCode 134 Gas Station 解题思路和python代码
  • 服务攻防
  • leetcode 力扣算法题 快慢指针 双指针 19.删除链表的倒数第n个结点
  • 网络五层模型:物理层、数据链路层、网络层、传输层、应用层,分别解决了什么问题?
  • OpenCV视频I/O(18)视频写入类VideoWriter之初始化 VideoWriter 对象的函数open()的使用
  • 大数据处理从零开始————4.认识HDFS分布式文件系统
  • jwt认证课件讲解
  • 【判断推理】逻辑基础
  • AcWing 655:天数转换 ← 整除、求余
  • 【解决办法】git clone报错unable to access ‘xxx‘: SSL certificate problem:
  • 算法笔记(十三)——BFS 解决最短路问题
  • Android 简单实现联系人列表+字母索引联动效果
  • 自动驾驶-问题笔记-待解决
  • 在掌控板中加载人教版信息科技教学指南中的educore库
  • 关于CSS Grid布局
  • 初始爬虫12(反爬与反反爬)
  • 成像基础 -- 最大对焦清晰的物距计算
  • win10服务器启动且未登录时自动启动程序
  • 算法专题四: 前缀和
  • 【Linux】基础IO(文件描述符、缓冲区、重定向)
  • 一篇文章快速学会docker容器技术
  • 【MySQL】使用 JDBC 连接数据库
  • 数据结构与算法笔记:概念与leetcode练习题
  • 十大时间序列预测模型