【Linux小项目】实现自己的bash

0. bash原理介绍

bash实际上就是一个负责解析输入字符串工具.

我们需要做的事是这些:

  1. 手动分割出输入的字符串
  2. 判断哪些变量是内建命令(自己执行),哪些命令是普通命令(创建子进程执行)
  3. 实现的功能有: echo export cd 常规指令 输入、输出流重定向
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<fcntl.h>#define HOST_NAME "hecs-225896"
#define LINE_SIZE 128
#define DELIM " "
#define SHEEL_COMMAND 0
#define NORMAL_COMMAND 1
#define IN_RESTREAM 0
#define OUT_RESTREAM 1
#define APPEND_RESTREAM 2 
#define NONE 0char pwd[LINE_SIZE];
char command[LINE_SIZE];
char* _argv[LINE_SIZE];
char myenv[LINE_SIZE];
int lastcode;
char * filename;
int restream = NONE;
int stream = 0;char * getpwd()
{return getcwd(pwd,sizeof(pwd));
}
char* getusr()
{return getenv("USER");
}
void interactive()
{char symbol;if(!strcmp(getenv("USER"),"root"))symbol='#';elsesymbol='$'; printf("%s@"HOST_NAME":""%s""%c ",getusr(),getpwd(),symbol);fgets(command,sizeof(command)-1,stdin);//消除'\n'command[strlen(command)-1]='\0';// printf("%s",command);
}
int split()
{for(int i=0;command[i];i++){if(command[i]=='>')  //写入重定向{command[i++]='\0';restream=OUT_RESTREAM;if(command[i]=='>') //追加重定向{restream=APPEND_RESTREAM;command[i++]='\0';while(command[i]==' ')i++;filename=command+i;printf("filename:%s\n",filename);stream=open(filename,O_CREAT|O_APPEND,0666);}else{while(command[i]==' ')i++;filename=command+i;printf("filename:%s\n",filename);stream=open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);}break;}else if(command[i]=='<'){restream=IN_RESTREAM;command[i++]='\0';while(command[i]==' ')i++;filename=command+i;printf("filename:%s\n",filename);stream=open(filename,O_RDONLY);break;}}int _argc=0;_argv[_argc++]=strtok(command,DELIM);while(_argv[_argc]=strtok(NULL,DELIM)){_argc++;}_argv[_argc]=NULL;return _argc;
}
int JudgeCommand()
{if(!strcmp(_argv[0],"cd")){return SHEEL_COMMAND;}else if(!strcmp(_argv[0],"echo")){return SHEEL_COMMAND;}else if(!strcmp(_argv[0],"export")){return SHEEL_COMMAND;}return NORMAL_COMMAND;
}
int execute_NormalCommand()
{pid_t id=fork();if(id<0){perror("fork faild\n");return 1;}else if(id==0){if(restream == OUT_RESTREAM || restream == APPEND_RESTREAM ){dup2(stream,1);}else if(restream == IN_RESTREAM){dup2(stream,0);}execvp(_argv[0],_argv);exit(2);}else if(id>0){int status=0;pid_t wid=waitpid(id,&status,0);if(wid==id)lastcode = WEXITSTATUS(status);}
}
int execute_ShellCommand(int argc)
{if(argc>=2&&!strcmp(_argv[0],"cd")){int rev=chdir(_argv[1]);if(rev!=0){perror("return faild");}}else if(argc>=2&&!strcmp(_argv[0],"echo")){if(_argv[1][0]=='$'){printf("%c",_argv[1][0]);char * env=getenv(_argv[1]+1);if(env)printf("%s\n",env);}else if(!strcmp(_argv[1],"?")){printf("%d\n",lastcode);lastcode=0;}elseprintf("%s\n",_argv[1]);}else if(argc>=2&&!strcmp(_argv[0],"export")){strcpy(myenv,_argv[1]);putenv(_argv[1]);}}
void BuildCommand(int *_argc)
{if(!strcmp(_argv[0],"ls")){_argv[(*_argc)++]="--color";_argv[*_argc]=NULL;}
}int main()
{while(1){interactive();int argc=split();if(argc==0)continue;// for(int i=0;i<argc;i++)printf("%s\n",_argv[i]);int RunFlag=JudgeCommand();BuildCommand(&argc);if(RunFlag==NORMAL_COMMAND){execute_NormalCommand();}else{execute_ShellCommand(argc);}}
}

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

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

相关文章

【计网 面向连接的传输TCP】 中科大笔记 (十 二)

目录 0 引言1 TCP 的特性1.1 拓展&#xff1a;全双工、单工、半双工通信 2 TCP报文段结构3 TCP如何实现RDT4 TCP 流量控制4.1 题外话&#xff1a;算法感悟 5 TCP连接3次握手、断开连接4次握手5.1 连接5.2 断开连接 6 拥塞控制6.1 拥塞控制原理6.2 TCP拥塞控制 &#x1f64b;‍♂…

MFC 发布CLXHHandleEngine动态库1.0.0.0版本

第一版发布以下功能&#xff0c;此项目使用VS2013创建&#xff0c;项目配置包括Unicode的Mdd,md与多字节版本&#xff1a; //MFC Grid表格 #include "../MFCGridCtrl/GridCtrl.h" //使用AES与Base64加密解密可以与java中的AES加解密衔接 //AES加密解密 #include &q…

基于python协同过滤推荐算法的音乐推荐与管理系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Python的协同过滤推荐算法的音乐推荐与管理系统是一个集成了音乐推荐和管理的系统&#xff0c;它使用协同过滤算…

19. Python 数据处理之 Pandas

目录 1. 认识 Pandas2. 安装和导入 Pandas3. Pandas 数据结构4. Pandas 基本功能5. Pandas 数据分析 1. 认识 Pandas Pandas 是 Python 的核心数据分析支持库&#xff0c;提供了快速、灵活、明确的数据结构&#xff0c;旨在简单、直观地处理关系型、标记型数据。 Pandas 的出…

HarmonyOS应用开发者基础认证【题库答案】

HarmonyOS应用开发者高级认证【题库答案】 一、判断 首选项preferences是以Key-Value形式存储数据&#xff0c;其中Key是可以重复。&#xff08;错&#xff09;使用http模块发起网络请求时&#xff0c;必须要使用on(‘headersReceive’&#xff09;订阅请求头&#xff0c;请…

一、Spring_IOCDI(1)

&#x1f33b;&#x1f33b; 目录 一、前提介绍1.1 为什么要学?1.2 学什么?1.3 怎么学? 二、Spring相关概念2.1 初始Spring2.1.1 Spring家族2.1.2 了解 Spring 发展史 2.2 Spring系统架构2.2.1 系统架构图2.2.2 课程学习路线 2.3 Spring核心概念2.3.1 目前项目中的问题2.3.2…

JBase到JRT

JBase之前是站在之前基础上新做的java框架。所以带入一些老的历史习惯&#xff0c;比如库和空间都以LIS开头&#xff0c;实体只能是LIS.Model等。为了做到更通用的框架&#xff0c;需要剔除LIS特性&#xff0c;实体肯定不能只能叫LIS.Model了。同时之前只关注业务脚本化的事忘了…

2023年程序设计迎新赛(第二届个人程序设计大赛)

7-1 找规律 请从所给的四个选项中&#xff0c;选择最合适的一个填入问号处&#xff0c;使之呈现一定的规律性。 输入格式: 无 输出格式: 大写字母 输入样例: 输出样例: #include<stdio.h> int main(){printf("D");return 0; }7-2 蜡烛燃烧时间 有粗细不同…

react项目自行配置热更新

react项目自己配置热更新的话需要安装两个包pmmmwh/react-refresh-webpack-plugin和react-refresh&#xff0c;这个是官方推荐的做法。下面给出一个完整demo App.js import React, { useState } from "react";function App() {const [count, setCount] useState(0…

【推荐系统】MMOE笔记 20231126

paper阅读 任务差异带来的固有冲突实际上会损害至少某些任务的预测&#xff0c;特别是当模型参数在所有任务之间广泛共享时。&#xff08;在说ESMM&#xff09; 共享底层参数可以减少过拟合风险&#xff0c;但是会遇到任务差异引起的优化冲突&#xff0c;因为所有任务都需要在…

MySQL的undo log 与MVCC

文章目录 概要一、undo日志1.undo日志的作用2.undo日志的格式3. 事务id&#xff08;trx_id&#xff09; 二、MVCC1.版本链2.ReadView3.REPEATABLE READ —— 在第一次读取数据时生成一个ReadView4.快照读与当前读 小结 概要 Undo Log&#xff1a;数据库事务开始之前&#xff0…

【nowcoder】BM4 合并两个排序的链表

题目&#xff1a; 题目分析&#xff1a; 题目分析转载 代码实现&#xff1a; package BMP4;import java.util.List;class ListNode {int val;ListNode next null;public ListNode(int val) {this.val val;} } public class BM4 {/*** 代码中的类名、方法名、参数名已经指定…

C语言中文网 - Shell脚本 - 10 - 第一个Shell脚本

第1章 Shell基础&#xff08;开胃菜&#xff09; 10. 第一个Shell脚本 几乎所有编程语言的教程都是从使用著名的“Hello World”开始的&#xff0c;出于对这种传统的尊重&#xff08;或者说落入俗套&#xff09;&#xff0c;我们的第一个 Shell 脚本也输出“Hello World”。 打…

记一次Kotlin Visibility Modifiers引发的问题

概述 测试环境爆出ERROR告警日志java.lang.IllegalStateException: Didnt find report for specified language&#xff0c;登录测试环境ELK查到如下具体的报错堆栈日志&#xff1a; java.lang.IllegalStateException: Didnt find report for specified language at com.aba.…

数组栈的实现

1.栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作 进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底 栈中的数据元素遵守后进先出LIFO,&#xff08;Last In First Out&#xff09;的原则 压栈&…

如何将 Python 运用到实际的测试工作中

1、自动化测试脚本编写&#xff1a; Python广泛用于编写自动化测试脚本&#xff0c;以执行各种测试任务。可以使用Selenium、Appium或PyTest等库来辅助测试脚本的编写。 下面是一个示例&#xff1a; from selenium import webdriver import unittestclass LoginTest(unittes…

[网络] 字节一面~ 2. HTTP 2 与 HTTP 1.x 有什么区别

头部压缩 在 HTTP2 当中&#xff0c;如果你发出了多个请求&#xff0c;并且它们的头部(header)是相同的&#xff0c;那么 HTTP2 协议会帮你消除同样的部分。(其实就是在客户端和服务端维护一张索引表来实现)二进制格式 HTTP1.1 采用明文的形式 HTTP/2 全⾯采⽤了⼆进制格式&…

简析range和xrange的区别

在 Python 2 中&#xff0c;存在 range() 和 xrange() 两个函数&#xff0c;但在 Python 3 中&#xff0c;xrange() 已经被移除&#xff0c;只剩下了 range() 函数。 主要区别在于它们返回的对象类型不同&#xff1a; range() 返回的是一个列表对象&#xff0c;它直接生成一个…

【科技素养】蓝桥杯STEMA 科技素养组模拟练习试卷8

1、一家餐馆同时有四个顾客点单&#xff0c;他们点的菜分别需要 12&#xff0c;15&#xff0c;20 和 30分钟的准备时间。在一次只能准备一份菜的情况下&#xff0c;四个顾客的等待时间之和最小是&#xff08;&#xff09;分钟 A、128 B、192 C、282 D、163 答案&#xff1…

[JVM] 美团二面,说一下JVM数据区域

Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。这些区域有不同的用途。 文章目录 线程私有的数据区域1. 程序计数器2. Java 虚拟机栈3. 本地方法栈 线程共享的数据区域1. Java 堆2. 方法区3. 运行时常量池4. 直接内存 线程私有的数据区域 …