【Linux小项目】实现自己的bash
0. bash原理介绍
bash实际上就是一个负责解析输入字符串工具.
我们需要做的事是这些:
- 手动分割出输入的字符串
- 判断哪些变量是内建命令(自己执行),哪些命令是普通命令(创建子进程执行)
- 实现的功能有: 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);}}
}
相关文章:
【Linux小项目】实现自己的bash
0. bash原理介绍 bash实际上就是一个负责解析输入字符串工具. 我们需要做的事是这些: 手动分割出输入的字符串判断哪些变量是内建命令(自己执行),哪些命令是普通命令(创建子进程执行)实现的功能有: echo export cd 常规指令 输入、输出流重定向 #include<stdio.h> #i…...
客户案例:EDLP助力金融行业打造高效数据防泄露体系
客户背景 某金融机构是一家以金融科技为核心,致力于为客户提供全方位、智能化、便捷化金融服务的综合性企业。公司总部位于南京,业务范围覆盖全国,拥有强大的技术研发团队和优秀的业务精英,为客户提供全方位的金融服务解决方案。 …...
【JavaFX漏扫开发基础】stage窗口/模式/模态
文章目录 stage一、stage窗口二、stage窗口,模式,模态stage模式(5种样式)模态化窗口stage stage其实就是一个窗口,它啥也不是,打开所有windows的程序都会有一个窗口,这个窗口就是javafx里的stage。里面的内容不属于stage,stage就是一个窗口,就这么简单。 Stage is a…...
MySQL进阶知识:锁
目录 前言 全局锁 表级锁 表锁 元数据锁(MDL) 意向锁 行级锁 行锁 行锁演示 间隙锁/临界锁 演示 前言 MySQL中的锁,按照锁的粒度分,分为以下三类 全局锁:锁定数据库中的所有表。表级锁:每次操…...
linux下的工具---gdb
一、gdb简介 GDB,是The GNU Project Debugger 的缩写,是 Linux 下功能全面的调试工具。 GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。 程序的发布方式有两种,debug模式和release模式 Linux gcc/g出来的二进制程序&am…...
ESP32-Web-Server编程-JS 基础 2
ESP32-Web-Server编程-JS 基础 2 概述 上节介绍了 JS 编程的基础。如前所述,在 HTML 中,可以通过下述 两种方式使用 JS 程序: 直接在 HTML 文件中通过 script 标签中嵌入 JavaScript 代码。通过 src 元素引入外部的 JavaScript 文件。 在…...
Java Web基础教程
Java Web基础教程 1. Servlet基础 1.1 什么是Servlet Servlet是JavaEE中的标准组件之一,专门用于处理客户端的HTTP请求。并且它必须依赖于Servlet容器(Tomcat就是一个标准的Servlet容器)才能运行。因为Servlet实例的创建和销毁都是由容器负…...
BUUCTF john-in-the-middle 1
BUUCTF:https://buuoj.cn/challenges 题目描述: 注意:得到的 flag 请包上 flag{} 提交 密文: 下载附件,解压得到john-in-the-middle.pcap文件。 解题思路: 1、双击文件,打开wireshark。 看到很多http流…...
HashMap的死循环及数据覆盖问题
目录 一,HashMap 线程不安全的原因 二,HashMap 死循环问题 死循环发生的条件 死循环的具体过程 死循环执行步骤1 死循环执行步骤2 死循环执行步骤3 三,HashMap 数据覆盖问题 数据覆盖执行流程1 数据覆盖执行流程2 数据覆盖执行流…...
数据库数据恢复—MongoDB数据库文件拷贝出现错误的数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统的虚拟机,虚拟机上部署有MongoDB数据库。 MongoDB数据库故障&检测: 在未关闭MongoDB服务的情况下,工作人员将MongoDB数据库文件拷贝到其他分区,然后将原数…...
2023年11月个人工作生活总结
本文为 2023 年 11 月工作生活总结。 研发编码 GIS 模仿了一些有名的地图服务商的网站,将离线地图页面做成全屏,对于大屏幕更加好友。再美化一下全区的边界和区内地域的边界。不过主要工作量还是绘制路线,而绘线作为内部工作,还…...
Spark-06:Spark 共享变量
目录 1.广播变量(broadcast variables) 2.累加器(accumulators) 在分布式计算中,当在集群的多个节点上并行运行函数时,默认情况下,每个任务都会获得函数中使用到的变量的一个副本。如果变量很…...
Spring整合web环境
目录 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 Spring的web开发组件spring-web MVC框架思想及其设计思路 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 package com.xfy.listener;import com.xfy.config.SpringConfig; import org.springfra…...
分享从零开始学习网络设备配置--任务4.3 使用动态路由RIPng实现网络连通
任务描述 某公司使用IPv6技术搭建企业网络,由于静态路由需要管理员手工配置,在网络拓扑发生变化时,也不会自动生成新的路由,因此采用IPv6动态路由协议RIPng实现网络连通,实现任意两个节点之间的通信,并降低…...
vue2.0+elementui集成file-loader之后图标失效问题
背景 跑vue2elementUI项目时,由于前端这边需要在本地存放xlsx模板文件,供用户下载模板文件,所以需要在webpack构建的时候增加file-loader进行解析xlsx文件打包。 vue版本2.x element-ui 版本 2.13.x 注意 npm i -D file-loader版本号给vue项…...
C# 文件帮助类(FileHelper)
引言 在研究程序反射的时候我们往往需要获取当前运行程序所引用的dll文件,按照传统的方式我们可以维护一个这样的列表,但是这样维护成本实在是太高,而且不利于团队合作开发,在高版本的.net 4.6.2之后官方出了专门的dll帮我们做这个事情Microsoft.Extensions.DependencyMod…...
WordPress 外链跳转插件
WordPress 外链跳转插件是本站开发的一款WordPress插件,能对文中外链添加一层过滤,有效防止追踪,以及提醒用户。 类似于知乎、CSDN打开其他链接的提示。 后台可以设置白名单 学习资料源代码:百度网盘 密码:123...
算法的10大排序
10大排序算法--python 一颗星--选择排序一颗星--冒泡排序一颗星--插入排序两颗星--归并排序(递归-难)三颗星--桶排序三颗星--计数排序四颗星--基数排序四颗星--快速排序,寻找标志位(递归-难)四颗星--又是比较难的希尔排…...
“十道机器学习问题,帮助你了解基础知识和常见算法“
目录 简介: 1. 什么是机器学习?它与传统编程有什么不同之处?2. 请解释监督学习和无监督学习的区别。3. 什么是过拟合和欠拟合?如何解决这些问题?4. 请解释交叉验证在机器学习中的作用。5. 什么是特征选择?为…...
部署WAF安全应用防火墙(openresty部署)
使用NGINX+Openresty实现WAF功能 一、了解WAF 1.1 什么是WAF Web应用防护系统(也称:网站应用级入侵防御系统 。英文:Web Application Firewall,简称: WAF)。利用国际上公认的一种说法:Web应用 防火墙 是通过执行一系列针对HTTP/HTTPS的 安全策略 来专门为Web应用提供保…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
TCP/IP 网络编程 | 服务端 客户端的封装
设计模式 文章目录 设计模式一、socket.h 接口(interface)二、socket.cpp 实现(implementation)三、server.cpp 使用封装(main 函数)四、client.cpp 使用封装(main 函数)五、退出方法…...
【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...
