【Linux】文件重定向与实现支持文件重定向的minishell


目录

0.前提

​编辑

1.重定向

1.1重定向的本质

1.2dup2

1.3模拟实现输出重定向 >

1.4模拟实现追加重定向 >>

1.5模拟实现输入重定向 <

2.让minishell支持重定向


0.前提

文件描述符的分配规则:

在文件描述符表里面,从小到大按照顺序寻找最小的且没有被占用的fd。


1.重定向

1.1重定向的本质

上层使用的fd不变,在内核中更改fd对应的struct file*的地址。

1.2dup2

让newfd变成oldfd的拷贝,如果需要关闭newfd.

1.3模拟实现输出重定向 >

1.4模拟实现追加重定向 >>

1.5模拟实现输入重定向 <

2.让minishell支持重定向

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<errno.h>#define B_NUM 1024
#define ARGV_NUM 10
#define NONE_REDIR 0
#define INPUT_REDIR 1
#define OUTPUT_REDIR 2
#define APPEND_REDIR 3char buffer[B_NUM];
char* myargv[ARGV_NUM];
int quitcode=0;
int quitsignal=0;int redirType=NONE_REDIR;
char* refilename=NULL;void Commandcheck(char* command)
{assert(command);//判断是否有重定向,有是哪种char* begin=command;char* end=command+sizeof command-1;while(begin<end)//while((*begin)!='\0'){if(*begin=='>'){*begin='\0';begin++;if(*begin=='>'){redirType=APPEND_REDIR;begin+=2;refilename=begin;}else{redirType=OUTPUT_REDIR;refilename=(++begin);break;}}if(*begin=='<'){*begin='\0';redirType=INPUT_REDIR;begin+=2;refilename=begin;break;}begin++;}return ;
}int main()
{while(1){redirType=NONE_REDIR;refilename=NULL;errno=0;printf("【用户名@服务器 当前目录】$");fflush(stdout);char* s=fgets(buffer,sizeof (buffer)-1,stdin);assert(s!=NULL);buffer[strlen (buffer)-1]=0;(void)s;//和重定向区分开Commandcheck(buffer);// printf("切割成功:命令 %s 文件 %s\n",buffer,refilename);//切割字符串myargv[0]=strtok(buffer," ");int i=0;if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0){myargv[++i] = (char*)"--color=auto";}while(myargv[i]!=NULL){myargv[++i]=strtok(NULL," ");}//实现cd功能if(myargv[0] != NULL &&strcmp(myargv[0],"cd")==0){if(myargv[1]!=NULL){chdir(myargv[1]);}continue;}//实现echo $?功能if(myargv[0]!=NULL&&myargv[1]!=NULL&&strcmp(myargv[0],"echo")==0){if(strcmp(myargv[1],"$?")==0){//输出上一个进程的退出码printf("退出码为:%d\n",quitcode);}else{printf("%s\n",myargv[1]);}continue;}pid_t id =fork();assert(id!=-1);if(id==0){//子进程//如果有文件打开文件switch(redirType){case NONE_REDIR:break;case INPUT_REDIR:{int fd=open(refilename,O_RDONLY);if(fd < 0){           perror("open");exit(errno);}dup2(fd,0);}break;case OUTPUT_REDIR:case APPEND_REDIR:{int flag=O_WRONLY|O_CREAT;if(redirType==OUTPUT_REDIR){flag|=O_TRUNC;}else{flag|=O_APPEND;}umask(0);int fd=open(refilename,flag,0666);if(fd < 0){            perror("open");exit(errno);}dup2(fd,1);}break;default:break;}//程序替换execvp(myargv[0],myargv); //如果走到这里表示替换失败exit(1);}//父进程int status=0;pid_t ret= waitpid(id,&status,0);assert(ret > 0);(void)ret;quitcode=(status>>8)&0XFF;quitsignal= (status & 0x7F);}return 0;
}

注意:每次父进程循环都要记得刷新 redirType 、redirFile、errno 


最后

加油

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

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

相关文章

uniapp中配置开发环境和生产环境

uniapp在开发的时候&#xff0c;可以配置多种环境&#xff0c;用于自动切换IP地址&#xff0c;用HBuilder X直接运行的就是开发环境&#xff0c;用HBuilder X发布出来的&#xff0c;就是生产环境。 1.使用HBuilder X创建原生的uniapp程序 选择vue3 2.什么都不改&#xff0c;就…

《Python 网络爬虫简易速速上手小册》第3章:Python 网络爬虫的设计(2024 最新版)

文章目录 3.1 设计高效的爬取策略3.1.1 重点基础知识讲解3.1.2 重点案例&#xff1a;使用 Scrapy 框架进行并发爬取3.1.3 拓展案例 1&#xff1a;使用 Requests 和 gevent 进行异步请求3.1.4 拓展案例 2&#xff1a;利用缓存机制避免重复请求 3.2 管理爬虫的请求频率3.2.1 重点…

React 中实现拖拽功能-插件 react-beautiful-dnd

拖拽功能在平时开发中是很常见的&#xff0c;这篇文章主要使用react-beautiful-dnd插件实现此功能。 非常好用&#xff0c;附上GitHub地址&#xff1a;https://github.com/atlassian/react-beautiful-dnd 安装及引入 // 1.引入 # yarn yarn add react-beautiful-dnd# npm npm…

uniapp android和微信小程序实现PDF在线预览

在使用uniapp开发移动端时&#xff0c;微信开发者工具里webview能正常打开后端接口返回的pdf文件流。正式发布后&#xff0c;在配置了业务域名和服务器域名的前提下&#xff0c;预览pdf文件却只能看到白屏&#xff0c;因此我猜测微信小程序不能通过webview读取文件流。这个想法…

【分布式】雪花算法学习笔记

雪花算法学习笔记 来源 https://pdai.tech/md/algorithm/alg-domain-id-snowflake.html概述 雪花算法是推特开源的分布式ID生成算法&#xff0c;以划分命名空间的方式将64位分割成多个部分&#xff0c;每一个部分代表不同的含义&#xff0c;这种就是将64位划分成不同的段&…

支持向量机

支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一个非常优雅的算法&#xff0c;具有非常完善的数学理论&#xff0c;常用于数据分类&#xff0c;也可以用于数据的回归预测中。支持向量机在许多领域都有广泛的应用&#xff0c;如文本分类、图像识别…

Alt + TAB 禁止在 Edge 标签页之间切换

&#xff08;原文&#xff1a;https://blog.iyatt.com/?p13587 &#xff09; 浏览器标签页之间切换可以用 {Ctrl}{Tab} 或者 {Ctrl}{数字}精准到标签页码&#xff0c;结果 Windows 11 默认把 Edge 标签页切换混入了 {Alt}{Tab} 前台应用窗口切换&#xff0c;经常不注意是在 Ed…

LeetCode:2.两数相加

目录 题目&#xff1a;​编辑2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 分析问题&#xff1a; 官方的优秀代码博主的注释&#xff1a; 博主的辣眼代码&#xff0c;无注释&#xff0c;拉出来拷打自己&#xff1a; 每日表情包&#xff1a; 2. 两数相加 - 力扣&am…

SpringBoot异步任务

一、注解实现 EnableAsync注解 创建一个配置类&#xff0c;并在类上添加EnableAsync注解&#xff0c;用来启用异步支持。 Configuration EnableAsync public class AsyncConfig { }或者&#xff0c;在启动类上添加EnableAsync注解&#xff0c;用来启用异步支持。 EnableAsy…

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案 大家好 我是寸铁&#x1f44a; 总结了一篇Error: only one service expected goctl一键转换生成rpc服务错误解决方案的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题背景 今天寸铁在…

最新GPT4.0使用教程,AI绘画,GPT语音对话使用,DALL-E3文生图

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;文档对话总结DALL-E3文生图&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和…

大模型日报-20240204

文章目录 大模型也有小偷&#xff1f;为保护你的参数&#xff0c;上交大给大模型制作「人类可读指纹」阿里全新Agent玩转手机&#xff1a;刷短视频自主点赞评论&#xff0c;还学会了跨应用操作代谢数据集上四项指标达94%~98%&#xff0c;西南交大团队开发多尺度图神经网络框架&…