【lesson38】让minishell支持重定向
文章目录
- minishell支持重定向
- minishell完整代码
minishell支持重定向
支持重定向的核心逻辑:
1.分析字符串是否含有重定向的符号,并且提取文件名。
#define INPUT_REDIR 0 //输入重定向
#define OUTPUT_REDIR 1 //输出重定向
#define APPEND_REDIR 2 //追加重定向
#define NONE_REDIR 4 //没有重定向
int redir_status = NONE_REDIR;//状态char* CheckRedir(char* start)
{ assert(start); char* end = start + strlen(start)-1; //end执行指令的最后一个内容 while(start < end) { if(*end == '>') { if(*(end -1) == '>') { //ls -a -l>>log.txt\0 追加redir_status = APPEND_REDIR; *(end-1) = '\0'; end++; break; } //ls -a -l>log.txt\0 输出redir_status = OUTPUT_REDIR; *(end) = '\0'; end++; break;}else if(*end == '<'){//ls -a -l<log.txt\0 输入redir_status = INPUT_REDIR;*end = '\0';end++;break;}else {end--;}}//循环结束,如果end还是大于start,说明存在重定向if(end > start){return end;}//走到这说明不存在重定向return NULL;
}
例子:
end开始向前找重定向符
然后end++
这样end指向的就是文件名,start执行的就是指令内容。
然后就开始在子进程进行重定向了。
//printf("parent process create subprocess success\n"); if(sep) { int fd = -1; switch(redir_status) { case INPUT_REDIR: fd = open(sep,O_RDONLY); dup2(fd,0); break; case OUTPUT_REDIR: fd = open(sep,O_WRONLY | O_CREAT | O_TRUNC,0666); dup2(fd,1); break; case APPEND_REDIR: fd = open(sep,O_WRONLY | O_CREAT | O_APPEND,0666); dup2(fd,1); break; default: assert(NULL); break; } }
minishell完整代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <assert.h>#define NUM 1024
#define SIZE 32
#define SEP " "#define INPUT_REDIR 0
#define OUTPUT_REDIR 1
#define APPEND_REDIR 2
#define NONE_REDIR 4
int redir_status = NONE_REDIR;char cmd_line[NUM];//array for saving command line
char* g_argv[SIZE];//the array are used to store paresed commands
char g_myval[64];char* CheckRedir(char* start)
{assert(start);char* end = start + strlen(start)-1;while(start < end) {if(*end == '>'){if(*(end -1) == '>'){//ls -a -l>>log.txt\0redir_status = APPEND_REDIR;*(end-1) = '\0';end++;break;}//ls -a -l>log.txt\0 redir_status = OUTPUT_REDIR;*(end) = '\0';end++;break;}else if(*end == '<'){//ls -a -l<log.txt\0redir_status = INPUT_REDIR;*end = '\0';end++;break;}else {end--;}}if(end > start){return end;}return NULL;
}
int main()
{//1.命令行解释器,一定是一个常驻内存的进程,不退出while(1) {//2.显示提示行printf("[xiaolin@localhost myshell]#");fflush(stdout);memset(cmd_line,'\0',sizeof cmd_line);//3.获取用户输入的字符串if(fgets(cmd_line,sizeof cmd_line,stdin) == NULL){//if cmd_line empty contiue get commandcontinue;}cmd_line[strlen(cmd_line)-1] = '\0';char* sep = CheckRedir(cmd_line);//4.对字符串进行解析int index = 0;g_argv[index++] = strtok(cmd_line,SEP);//Firest parse cmd_line while(1)//Second parse cmd_line don't pass cmdline;{g_argv[index] = strtok(NULL,SEP);if(g_argv[index] == NULL) break;index++;}if(strcmp(g_argv[0],"ls") == 0){g_argv[index++] = (char*)"--color=auto";g_argv[index] = NULL;} if(strcmp(g_argv[0],"ll") == 0){ g_argv[0] = (char*)"ls";g_argv[1] = (char*)"-l";g_argv[2] = (char*)"--color=auto";g_argv[3] = NULL;}// processing of built-in commandsif(strcmp(g_argv[0],"cd") == 0){//chdir() changes the current working directory of the calling process to the directory specified in path.if(g_argv[1] != NULL) chdir(g_argv[1]);continue;}if(strcmp(g_argv[0],"export") == 0 && g_argv[1] != NULL){//There is a very hidden issue here//Ptuenv passes an environment variable as a pointer to it //And g_ Argv [1] will be cleared on the next command_line read//In this way, the environment variable pointer points to a place with empty data, and this pointer is also a null pointer//int res = putenv(g_argv[1]);//if(res == 0) printf("export success\n");//else printf("export fail\n");//solve the problemstrcpy(g_myval,g_argv[1]);int res = putenv(g_myval);if(res == 0) printf("export success\n");else printf("expor fail\n");continue;}/*//test if the g_argv array id correct for(index = 0; g_argv[index]; index++){printf("g_argv[%d]:%s\n",index,g_argv[index]);}*///5.create subprocess execute commandpid_t id = fork();if(id == 0){//subprocess//printf("parent process create subprocess success\n");if(sep){int fd = -1;switch(redir_status){case INPUT_REDIR:fd = open(sep,O_RDONLY);dup2(fd,0);break;case OUTPUT_REDIR:fd = open(sep,O_WRONLY | O_CREAT | O_TRUNC,0666);dup2(fd,1);break;case APPEND_REDIR:fd = open(sep,O_WRONLY | O_CREAT | O_APPEND,0666);dup2(fd,1);break;default:assert(NULL); break;}}printf("subprocess starts running\n");execvp(g_argv[0],g_argv);printf("subprocess replace fail\n");}else if(id > 0){//parent processint status = 0;pid_t res = waitpid(-1,&status,0);//blocking waitingif(res == -1){printf("parent process wait subprocess fail\n");}else if(res > 0){printf("parent process wait subprocess success exit_code:%d\n",WEXITSTATUS(status));}else {printf("unkown error\n");}}else{//failprintf("parent procrss create subprocess fail\n");}}return 0;
}
相关文章:

【lesson38】让minishell支持重定向
文章目录 minishell支持重定向minishell完整代码 minishell支持重定向 支持重定向的核心逻辑: 1.分析字符串是否含有重定向的符号,并且提取文件名。 #define INPUT_REDIR 0 //输入重定向 #define OUTPUT_REDIR 1 //输出重定向 #define APPEND_REDIR…...

【安装指南】maven下载、安装与配置详细教程
🌼一、概述 maven功能与python的pip类似。 Apache Maven是一个用于软件项目管理和构建的强大工具。它是基于项目对象模型的,用于描述项目的构建配置和依赖关系。以下是一些关键的 Maven 特性和概念: POM(Project Object Model&…...

matplotlib-中文乱码问题解决方案
前言 本文主要解决matplotlib在画图时,出现的中文乱码问题,具体问题示意如下: 下面将针对这个问题直接给出具体的解决步骤。 具体步骤 1、首先去网上下载并安装SimHei字体,其它字体也行,如下 并将它安装在此目录下…...

Redis(十一)单线程VS多线程
文章目录 概述为何选择单线程主要性能瓶颈多线程特性和IO多路复用概述Unix网络编程中的五种IO模型Blocking IO-阻塞IONoneBlocking IO-非阻塞IOIO multiplexing-IO多路复用signal driven IO-信号驱动IOasynchronous IO-异步IO 场景:引出epoll总结 开启Redis多线程其…...

【微服务】Spring Boot集成ELK实用案例
推荐一款我一直在用国内很火的AI网站,包含GPT3.5/4.0、文心一言、通义千问、智谱AI等多个AI模型,支持PC、APP、VScode插件同步使用,点击链接跳转->ChatGPT4.0中文版 一、前言 在现代软件开发中,微服务架构已成为一种流行趋势。…...

已解决: ImportError: cannot import name ‘relu‘ from ‘keras.layers‘ 问题
博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …...

python-产品篇-火车票分析助手
文章目录 开发环境要求运行方法PyCarmVsCode 代码效果 开发环境要求 本系统的软件开发及运行环境具体如下。 (1)操作系统:操作系统:Windows 7、Windows 8、Windows 10。 (2)Python版本:Python …...

设计一个可以智能训练神经网络的流程
设计一个可以智能训练神经网络的流程,需要考虑以下几个关键步骤: 初始化参数:设定初始的batch size和learning rate,以及其他的神经网络参数。训练循环:开始训练过程,每次迭代更新网络的权重。监控loss:在每个训练周期(epoch)后,监控loss的变化情况。动态调整:根据l…...
自然语言处理(02/10):自然语言处理任务和应用程序
一、描述 在广阔的人工智能领域,自然语言处理 (NLP) 是一个迷人而充满活力的领域。NLP 弥合了计算机和人类语言之间的鸿沟,使机器能够理解、解释和生成类似人类的文本。这项变革性技术具有深远的影响,影响着我们日常生…...
Jmeter学习系列之三:测试计划详细介绍
目录 前言 步骤1:启动JMeter窗口 步骤2:添加/删除测试计划元素 步骤3:加载并保存测试计划元素。 步骤4:配置树元素 步骤5:保存JMeter测试计划 步骤6:运行JMeter测试计划...

mermaid使用指南+notion使用实例-持续更新中
最近一个月了吧,发现Notion插入图片的功能坏了,直接paste会404,本地上传也不行。电脑本地版和手机端都插不了图片,很头疼。解决方法也简单,用图床,放链接。 付费版我用的七牛,结合PicGo&#x…...

Pytroch 自写训练模板适合入门版 包含十五种经典的自己复现的一维模型 1D CNN
训练模板 在毕业之前,决定整理一下手头的代码,自己做1D-CNN这吗久,打算开源一下自己使用的1D-CNN的代码,包括用随机数生成一个模拟的数据集,到自己写的一个比较好的适合入门的基础训练模板,以及自己复现的…...
【30秒看懂大数据】变量
简单说 变量是指研究或观察中可能发生变化的事物、属性或特征,它们可以用来描述数据或现象的不同方面。 举例理解 一位热衷于烹饪的大厨老李,经常尝试不同的菜肴来满足不同顾客的口味。 1. 老李明白,每种食材都等同于一个重要的变量…...
Redis - 多集群数据源配置
目录 前言依赖yml配置redis多集群数据源配置类思考 redis工具类 前言 工作时有一个项目配置了多个redis数据源,使用时出现了指定了使用副数据源,数据却依然使用了主数据源的情况。经过排查,发现配置流程较为繁琐易错,此处做一个记…...
五大架构风格之四-虚拟机架构风格
虚拟机架构风格: 虚拟机架构风格是一种软件架构,它通过模拟完整的计算机系统(包括硬件)来运行程序。这种风格的核心是虚拟机监控器。如最出名的虚拟机VM,在使用虚拟机架构,一个或多个虚拟机可以在单一物理主…...
在 C# 中 checked 和 unchecked 关键字
在 C# 中,checked 和 unchecked 是用于控制整数运算溢出检查的关键字。它们允许我们明确指定在进行整数运算时是否要检查溢出,以及如何处理溢出情况。 默认情况下,C# 中的整数运算是未检查的,也就是说,当运算结果溢出…...

【算法分析与设计】跳跃游戏
📝个人主页:五敷有你 🔥系列专栏:算法分析与设计 ⛺️稳中求进,晒太阳 题目 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断…...
openssl3.2 - helpdoc - P12证书操作
文章目录 openssl3.2 - helpdoc - P12证书操作概述笔记/doc/html/man1/CA.pl.htmlCA.pl -newcaCA.pl -newreqCA.pl -signCA.pl -pkcs12 "My Test Certificate"/doc/html/man1/openssl-pkcs12.html备注END openssl3.2 - helpdoc - P12证书操作 概述 D:\3rd_prj\cryp…...

【产业实践】使用YOLO V5 训练自有数据集,并且在C# Winform上通过onnx模块进行预测全流程打通
使用YOLO V5 训练自有数据集,并且在C# Winform上通过onnx模块进行预测全流程打通 效果图 背景介绍 当谈到目标检测算法时,YOLO(You Only Look Once)系列算法是一个备受关注的领域。YOLO通过将目标检测任务转化为一个回归问题,实现了快速且准确的目标检测。以下是YOLO的基…...

【操作系统】HeapByteBuffer和DirectByteBuffer的区别
DirectByteBuffer和HeapByteBuffer是Java NIO中ByteBuffer的两种实现方式。 HeapByteBuffer是在Java堆上分配的字节缓冲区,它使用数组来存储数据。HeapByteBuffer的优点是它具有良好的兼容性和可移植性,且在大多数情况下性能表现良好。它适用于大部分的…...

Photoshop2025(PS2025)软件及安装教程
在数字图像编辑领域,Adobe Photoshop 一直是无可争议的王者。如今,Photoshop 2025 重磅登场,再次为我们带来了惊喜与变革,进一步巩固了它在行业中的领先地位。 Photoshop 2025 在人工智能方面的升级令人瞩目。其全新的 “Magic Se…...

GD32F103系列工程模版创建记录
准备条件: 1:首先需要下载GD32F103的官方库 2:GD32F103的软件包 3:KEIL5软件 4:单片机GD32F103C8T6 本文已经默认KEIL5已将安装好GD32F103的软件包了 步骤一 基本模版创建 1 打开KEIL5软件,新建工程&am…...
Apache SeaTunnel 引擎深度解析:原理、技术与高效实践
Apache SeaTunnel 作为新一代高性能分布式数据集成平台,其核心引擎设计融合了现代大数据处理架构的精髓。 Apache SeaTunnel引擎通过分布式架构革新、精细化资源控制及企业级可靠性设计,显著提升了数据集成管道的执行效率与运维体验。其模块化设计允许用…...

Qt -下载Qt6与OpenCV
博客主页:【夜泉_ly】 本文专栏:【暂无】 欢迎点赞👍收藏⭐关注❤️ 前言 呃啊,本来就想在 Qt 里简单几个 OpenVC 的函数,没想到一搞就是一天。 我之前的开发环境是 Qt 5.14.2,使用 MinGW 7.3.0 64-bit 编…...

Ollama(1)知识点配置篇
ollama已经成功安装成功后,通常大家会对模型的下载位置和访问权限进行配置 1.模型下载位置修改 都是修改系统环境变量。 (1)默认下载位置 macOS: ~/.ollama/modelsLinux: /usr/share/ollama/.ollama/modelsWindows: C:\Users\你的电脑用户…...

5G RedCap是什么-与标准5G的区别及支持路由器推荐
技术背景与重要性 从智能穿戴到工业传感器,物联网设备种类繁多,但并非所有设备都需要标准5G的全部功能。为满足这些中端应用的需求,3GPP在Release 17中引入了5G RedCap(Reduced Capability),也称为5G NR-L…...

实验设计与分析(第6版,Montgomery)第4章随机化区组,拉丁方, 及有关设计4.5节思考题4.18~4.19 R语言解题
本文是实验设计与分析(第6版,Montgomery著,傅珏生译) 第章随机化区组,拉丁方, 及有关设计4.5节思考题4.18~4.19 R语言解题。主要涉及方差分析,拉丁方。 batch <- c(rep("batch1",5), rep(&quo…...
数据交易场景的数据质量评估
在现代数字化时代,数据已成为推动商业发展的核心驱动力。基于不同的交易产品和业务场景,数据产品的质量和准确性直接影响到数据资产的价值及其在市场中的流通性。因此,为数据产品提供全面、深入的数据质量评估报告,不仅有助于提升…...
CQF预备知识:Python相关库 -- NumPy 基础知识 - 通用函数
文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。 通用函数 另请参阅 通用函数(ufunc) 通用函数(或简称 ufunc)是一种对 ndarrays 进行逐元素操…...

brep2seq 论文笔记
Brep2Seq: a dataset and hierarchical deep learning network for reconstruction and generation of computer-aided design models | Journal of Computational Design and Engineering | Oxford Academic 这段文本描述了一个多头自注意力机制(MultiHead Attenti…...