Linux进程控制——进程程序替换、bash的模拟实现

文章目录

    • exec系列函数
      • execl
      • execlp和execle
    • execv系列函数
    • bash的模拟实现
      • 实现思路
      • 完整代码
      • 其他问题

在学习进程的时候,我们想fork一个子进程,然后就可以给他布置任务了

但是如果我们分成两个人开发,父子进程分别负责不同的任务,等待开发完成之后除了合并项目或者复制粘贴还有更好的办法吗

其实是有的,当子进程被创建后不想执行父进程代码时,就需要用到程序替换

主要是exec系列函数的用法

exec系列函数

在这里插入图片描述

这里一共有六个函数,但是是同一个系列的,也有一定的规律,如果他们替换失败了,返回值都是-1

execl

这是里面最简单的函数,他的函数有两个,第一个是执行的程序路径,之后的是参数包,表示如何执行该程序

可以理解为前一个是环境变量,后一个是程序指令,只不过按单词分开,具体使用是这样的

例如

#include<stdio.h>
#include<unistd.h>
int main()    
{    printf("程序替换\n");    int n = execl("/usr/bin/ls","ls","-a","-l",NULL);if(n==-1)    {    perror("execl");    }    printf("程序替换\n");    return 0;    
}    

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果是这样的,我们发现执行完execl之后执行了ls命令,而最后的输出命令却没有执行

说明execl之后,当前进程的代码和数据就和之前完全完全替换了,未执行的代码也会直接替换

execl的l是list的意思,其实就是要把执行程序的路径列举出来

execlp和execle

execlp的调用如下

#include<stdio.h>
#include<unistd.h>
int main()    
{    printf("程序替换\n");    int n = execlp("ls","-l",NULL);  if(n==-1)    {    perror("execlp");    }    printf("程序替换\n");    return 0;    
} 

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里我们可以发现execlp函数可以不用加路径,这其实是因为他可以自动检索环境变量,p的含义就是PATH

execle的调用如下

#include<stdio.h>
#include<unistd.h>
int main()    
{    const char* _env[]={"MY_ENV=114",NULL};    printf("进行程序\n");    int n = execle("/usr/bin/ls","ls","-l",NULL,_env); // 定义一个环境变量MY_ENV=114传递给要去执行的程序if(n==-1)    {    perror("execle");    }    printf("程序替换\n");    return 0;    
}  

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

execle可以在执行程序之前传入自己的环境变量,e是env的意思

execv系列函数

execv的v是vector的意思,也就是向量或者数组,可以理解为利用数组来传参

在这里插入图片描述

execv的使用如下

#include<stdio.h>
#include<unistd.h>
int main()    {    char* const set[]={"ls","-a","-l",NULL};  printf("程序替换\n");    int n = execv("/usr/bin/ls",set); if(n==-1)    {    perror("execv");    }    printf("程序替换\n");    return 0;    } 

这里的使用和上面其实差距不大,包括execvp和execvpe都是类似的,需要注意的是需要在最后加一个NULL表示数组结束

bash的模拟实现

一般情况下程序替换并非将自己进行替换,而是将fork出的子进程替换,自己来负责传达命令,回收子进程

实现思路

首先我们可以肯定的是bash是一共while死循环,因为他会不断的给我们打印提示信息

我们要模拟实现就可以自行定义其中的内容

例如

#include<stdio.h>
int main()
{while(true){// 提示信息printf("[leaf @ MyBash]$ ");fflush(stdout);// ...}return 0;
}

在模拟实现之前我们需要梳理一下思路

bash的功能是将用户输入的字符串打散之后变成一共字符串数组,将这个字符串数组分配给子进程让他去进行程序替换,最后等待回收资源即可

这里我们可以确定的是需要保存完整的用户输入的命令行字符串,大三之后的字符串数组,之后还有一些细节进行处理

#define NUM 1000 // 一行命令最长字符数
#define SIZE 16 // 一行命令最多单词数
char input_line[NUM]; // 完整输入命令
char* line_argv[SIZE]; // 打散后的字符串数组
if(fgets(input_line, sizeof(input_line), stdin) == NULL) // fget保存到数组continue;
input_line[strlen(input_line)-1] = '\0'; // 覆盖换行

将整个字符串打散我们可以使用strtok函数

在这里插入图片描述

line_argv[0] = strtoc(input_line, " "); // 第一个单词
int index = 1;
while(line_argv[index++] = strtok(NULL, " ")); // 之后的每一个单词

这样最麻烦的处理用户输入的部分就解决了,完整代码如下

完整代码

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#define NUM 1000 // 一行命令最长字符数
#define SIZE 16 // 一行命令最多单词数
char input_line[NUM]; // 完整输入命令
char* line_argv[SIZE]; // 打散后的字符串数组int main()
{while(1){// 提示信息printf("[leaf@MyBash]$ ");fflush(stdout);// 获取输入memset(input_line, '\0', sizeof(input_line));if(fgets(input_line, sizeof(input_line), stdin) == NULL) // fget保存到数组continue;input_line[strlen(input_line)-1] = '\0'; // 覆盖换行// 处理输入line_argv[0] = strtok(input_line, " "); // 第一个单词int index = 1;while(line_argv[index++] = strtok(NULL, " ")); // 之后的每一个单词// 子进程pid_t id = fork();if(id == 0){printf("子进程\n");execvp(line_argv[0], line_argv);exit(1);}int status = 0;pid_t ret = waitpid(-1, &status, 0);if(ret > 0)printf("exit code: %d\n", WEXITSTATUS(status));}return 0;
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当然如果你愿意的话也可以获取当前的目录也打印在提示信息中

其他问题

我们之前介绍过内建命令,说这种命令只能让父进程调用,例如cd命令,因为写时拷贝,子进程进了某个文件夹,对父进程是没有影响的,也只有在父进程执行才有意义

if(strcmp(line_argv[0], "cd")==0)
{if(my_argv[1]!=NULL)chdir(my_argv[1]); // 切换当前工作目录continue;
}

还有例如export,kill,history都是内建命令

其实在Linux环境下,程序替换不仅可以替换C语言程序,甚至可以替换成Python程序、Java程序去执行他们的内部代码,这就变相实现了不同语言之间的联动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/388536.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程小白如何成为大神?大学新生的最佳入门攻略

目录 方向一&#xff1a;选择适合的编程语言 方向二&#xff1a;制定有效的学习计划 方向三&#xff1a;避免常见的学习陷阱 方向四&#xff1a;额外建议 编程已成为当代大学生的必备技能&#xff0c;但面对众多编程语言和学习资源&#xff0c;新生们常常感到迷茫。如何选择…

深度学习模型服务端部署——flask+gunicorn+supervisor+nginx+docker

前言&#xff1a;深度学习模型经过前期的训练调优评估&#xff0c;最终得到一个精度速度满足要求的模型(.pth, .ckpt&#xff0c;或者.onnx等等格式)&#xff0c;但模型要实际用起来&#xff0c;还得部署起来&#xff0c;部署分为在移动端芯片上和服务器上。在移动端芯片部署通…

大龄程序员转型攻略:拥抱人工智能,开启新征程

前言 随着科技的飞速发展&#xff0c;人工智能浪潮席卷全球&#xff0c;相关岗位炙手可热。在这个背景下&#xff0c;许多大龄程序员开始思考如何转型&#xff0c;以适应时代的变化。结合自身编程基础&#xff0c;大龄程序员可以学习机器学习、深度学习算法&#xff0c;投身于…

蓝桥杯 Python 研究生组-2023-省赛-工作时长

蓝桥账户中心https://www.lanqiao.cn/problems/3494/learning/ 问题描述 小蓝手里有一份 20222022 年度自己的上班打卡记录文件&#xff0c;文件包含若干条打卡记录&#xff0c;每条记录的格式均为“yyyy-MM-dd HH:mm:ssyyyy-MM-dd HH:mm:ss”&#xff0c;即按照年-月-日 时:…

转录组数据去批次方法整理(combat,combat-seq,removeBatchEffect)

为什么需要去除批次效应&#xff1f; 批次效应是指样本在不同批次处理及测量的情况下引入与生物学情况不相关的技术误差&#xff0c;比如不同试剂耗材&#xff0c;不同操作者&#xff0c;不同的实验时间等。 正是因为这些非生物学的因素存在就有可能会导致我们的结果偏离真实…

网络通信---UDP

前两天做了个mplayer项目&#xff0c;今日继续学习 网络内容十分重要&#xff01;&#xff01;&#xff01; 1.OSI七层模型 应用层:要传输的数据信息&#xff0c;如文件传输&#xff0c;电子邮件等&#xff08;最接近用户&#xff0c;看传输的内容类型到底是什么&#xff09; …

精进日常:每日练习与明智取舍的艺术

目录 题目1.对于非运行时异常&#xff0c;程序中一般可不做处理&#xff0c;由java虚拟机自动进行处理。2.下面哪个关键字可以用于Java的构造方法上&#xff1f;3.以下代码执行的结果显示是多少&#xff08; &#xff09;&#xff1f;注解总结 题目 选自牛客网 1.对于非运行时…

[工具推荐]前端加解密之Burp插件Galaxy

如果觉得该文章有帮助的&#xff0c;麻烦师傅们可以搜索下微信公众号&#xff1a;良月安全。点个关注&#xff0c;感谢师傅们的支持。 免责声明 本号所发布的所有内容&#xff0c;包括但不限于信息、工具、项目以及文章&#xff0c;均旨在提供学习与研究之用。所有工具安全性…

前后端demo-WarehouseManagement

前端 数据库 其他 1.git下来&#xff0c;解决依赖问题&#xff0c;前端报错因为字体文件丢失&#xff0c;下载字体放到fonts文件夹字体.zip官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 2.后端login验证&#xff0c;前端需要账号格式&#xff0c;linqq.com 3.自己…

国产麒麟操作系统下搞单机版

去年纪委单位的一个项目&#xff0c;因为单位保密性质&#xff0c;档案必须要保密&#xff0c;要求采用单机版&#xff0c; 要求跟EXE那样&#xff0c;双击打开&#xff0c;阿公单位信息人员电脑操作水平化滞后还是相当严重啊。 去年已经给他花了时间按他们的要求实现了。 上周…

嵌入式C++、ROS 、OpenCV、SLAM 算法和路径规划算法:自主导航的移动机器人流程设计(代码示例)

在当今科技迅速发展的背景下&#xff0c;嵌入式自主移动机器人以其广泛的应用前景和技术挑战吸引了越来越多的研究者和开发者。本文将详细介绍一个嵌入式自主移动机器人项目&#xff0c;涵盖其硬件与软件系统设计、代码实现及项目总结&#xff0c;并提供相关参考文献。 项目概…

Day14-Servlet后端验证码的实现

图片验证码的生成采用的是Kaptcha&#xff1b; Kaptcha是一个高度可配置的验证码生成工具&#xff0c;由Google开源。它通过一系列配置文件和插件&#xff0c;实现了将验证码字符串自动转换成图片流&#xff0c;并可以与session进行关联&#xff0c;从而在验证过程中使用&#…

unity2D游戏开发17战斗精灵

导入 将PlayerFight32x32.png拖Player文件夹进去 设置属性 创建动画剪辑 选中前四帧,右键Create|Animation,将动画命名为player-ire-east 其他几个动画也创建好后,将其拖到Animations|Animations文件夹 选中PlayerController,再点击Animator 创建新的Blend Tree Graph,并重…

mysql逻辑架构与sql执行过程

目录 1.背景 2.mysql逻辑架构图 3.逻辑架构解读 第一层:连接层 第二层:服务层 1.Management Serveices & Utilities 2.SQL Interface:SQL接口 3.Parser:解析器 4.Optimizer:查询优化器 5.Caches 和 Buffers:查询缓存组件 第三层:存储引擎层 第四层:数据存储层 …

后端笔记(2)--JDBC

1.JDBC简介 *JDBC(Java DataBase Connectivity)就是使用java语言操作关系型数据库的一套API *JDBC本质&#xff1a;&#xff08;可以使用同一套代码&#xff0c;操作不同的关系型数据库&#xff09; ​ *官方定义的一套操作所有关系型数据库的规则&#xff0c;即接口 ​ *各…

基于java的人居环境整治管理系统(源码+lw+部署文档+讲解等)

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝20W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…

“八股文”面试题:是招聘程序员的金科玉律?

引言 随着互联网的发展&#xff0c;现代企业对程序员的需求日益增加。在招聘过程中&#xff0c;许多公司采用了“八股文”式的面试题目来筛选候选人。这些题目往往涵盖了算法、数据结构、系统设计等方面的基础知识。然而&#xff0c;对于“八股文”在实际工作中的作用&#xf…

为什么越来越多的IT青年转行网络安全?

目前&#xff0c;我国互联网已经从爆发增长期进入平稳发展阶段&#xff0c;同时每年大量计算机相关专业的毕业生涌入就业市场&#xff0c;导致IT行业逐渐趋于饱和状态&#xff0c;甚至出现裁员现象&#xff0c;去年很多大厂都有裁员&#xff0c;不少程序员再就业成了难题。 面…

网络安全相关工作必须要有证书吗?

在当今数字化时代&#xff0c;网络安全已成为至关重要的领域。然而&#xff0c;对于从事网络安全相关工作的人员来说&#xff0c;证书是否是必不可少的呢? 一、网络安全证书的重要性 网络安全证书在一定程度上能够证明从业者具备相关的知识和技能。例如&#xff0c;CISP 作为国…

昇思25天学习打卡营第XX天|RNN实现情感分类

希望代码能维持开源维护状态hhh&#xff0c;要是再文件整理下就更好了&#xff0c;现在好乱&#xff0c;不能好fork tutorials/application/source_zh_cn/nlp/sentiment_analysis.ipynb MindSpore/docs - Gitee.com