当前位置: 首页 > news >正文

Linux重定向

在这里插入图片描述

文章目录

    • 1. 文件描述符分配规则
    • 2. 重定向接口
      • dup2
      • 自定义shell重定向(补充)
    • 3. 标准输出和标准错误
    • 4. 如何理解一切接文件

本章代码gitee地址:文件重定向

1. 文件描述符分配规则

文件描述符的分配规则是从0下标开始,寻址最小的没有使用的数组位置,它的下标就是新文件的文件描述符。

我们来看一个现象:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>#define filename "log.txt"
int main()
{close(1);int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open");return 1;}const char *str = "hello linux\n";int cnt = 5;while(cnt--){write(1,str,strlen(str));}close(fd);return 0;
}

这段代码本应该是想1号文件描述符写入,也就是向显示屏输出信息。我们将这个1号文件描述符指向的显示器文件关闭了,运行结果没有显示出来,这个符合预期。可是,我们发现原本应该向显示器文件写入的内容,却写进了log.txt这个文件。

image-20231107190948481

这个过程就叫做——输出重定向

我们将1号文件描述符关闭,将进程与显示器对应的关联关系去掉。这个1号位置就空出来了,然后我们重新打开一个文件,那么正好1号文件描述符指向的内容是空的,然后就与该文件建立关联关系,所以内容写入这个文件

2. 重定向接口

如果我们想将某个内容重定向,其实不需要我们自己每次都手动关闭某个文件描述符,再去覆盖,系统为我们还提供了一些接口。

dup2

man 2 dup2

image-20231109105208160

这里的并不是拷贝文件描述符,因为文件描述符只是一个数组的下标,本质上拷贝的是文件描述符指向的内容

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>#define filename "log.txt"
int main()
{//close(1);int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open");return 1;}dup2(fd,1);close(fd);const char *str = "hello linux\n";int cnt = 5;while(cnt--){write(1,str,strlen(str));}//close(fd);return 0;
}

image-20231109112020545

我们这里就能看到,原本应该向显示器文件输出的内容,重定向到了log.txt文件当中。

重定向的本质就是将文件描述表当中的文件地址做拷贝

自定义shell重定向(补充)

有了这些知识原理,就能写出自己的重定向代码

不了解的可以查看这篇文章——Linux实现简易shell

#define NONE -1
#define IN_RDIR 0
#define OUT_RDIR 1
#define APPEND_RDIR 2
char *rdirfilename = NULL;
int redir = NONE;void check_redir(char *cmd)
{char *pos = cmd;while(*pos){if(*pos == '>'){if(*(pos+1) == '>'){*pos++ = '\0';*pos++ = '\0';while(isspace(*pos))  pos++;rdirfilename = pos;redir = APPEND_RDIR;break;}else{*pos++ = '\0';while(isspace(*pos))  pos++;rdirfilename = pos;redir = OUT_RDIR;break;}}else if(*pos == '<'){*pos++ = '\0';while(isspace(*pos))  pos++;rdirfilename = pos;redir = IN_RDIR;break;}else{//不改变}pos++;}
}void normalExcute(char *_argv[])
{pid_t id = fork();if(id < 0){perror("fork fail");return; }else if(id == 0){//判断是否重定向int fd = 0;if(redir == IN_RDIR) //输入重定向{fd = open(rdirfilename,O_RDONLY);dup2(fd,0);}else if(redir == OUT_RDIR) //输出重定向{fd = open(rdirfilename,O_CREAT|O_WRONLY|O_TRUNC,0666);dup2(fd,1);}else if(redir == APPEND_RDIR)  //追加重定向{fd = open(rdirfilename,O_CREAT|O_WRONLY|O_APPEND,0666);dup2(fd,1);}//子进程执行命令//execvpe(_argv[0],_argv,environ);  //直接程序替换execvp(_argv[0],_argv);   //直接替换程序exit(EXIT_CODE);  //替换失败的退出码}else{//父进程等待子进程退出int status = 0;pid_t rid = waitpid(id,&status,0);  //阻塞等待if(rid == id){lastcode = WEXITSTATUS(status);}}
}

这里的重定向并不会影响到之后的程序替换

因为这里的进程结构体或者是文件结构体,都是属于内核的数据结构,而我们的程序替换是由程序地址空间通过页表来进行一个替换,这也将程序替换和重定向工作进行了解耦

3. 标准输出和标准错误

标准输出stdou和标准错误stderr都是显示器文件输出内容,那他们这两个有什么区别呢

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>#define filename "log.txt"
int main()
{fprintf(stdout,"hello stdout\n");fprintf(stdout,"hello stdout\n");fprintf(stdout,"hello stdout\n");fprintf(stderr,"hello stderr\n");fprintf(stderr,"hello stderr\n");fprintf(stderr,"hello stderr\n");return 0;
}

这里我们运行,确实是发现,都是往显示器文件上输出内容

image-20231111192917656

但是如果我们重定向,这里发现往标准错误输入的内容并没有重定向到我们的目标文件当中,而标准输出的内容被重定向到了目标文件

image-20231111193053970

通过这里我们可以验证,>这个输出重定向的符合,默认就是将一个号文件描述符的内容重定向到目标

image-20231111193321663

但是我们也可以指定将几号文件描述符指向的内容重定向到目标文件当中

这里有个2>&1,意思就是将一号文件描述符的内容拷贝到二号文件描述符当中,让其和1指向同一个文件

4. 如何理解一切接文件

所以操作计算机的动作,都是以进程的形式进行操作的;所以访问文件的操作,也都是以进程的形式访问的。

在计算机里面,存在着各种设备,例如键盘、显示器、磁盘、网卡…,这些都被称之为外设

操作系统和这些外设打交道的时候,都需要它们所对应的方法,例如显示要有读的方法、键盘要有读写方法…每个外设都要有其对应读写方法,这个简称为IO

因为在linux下一切皆文件,所以在操作系统看来,这些外设都是文件,而访问文件的操作,都是以进程的形式访问。linux内核里面又提供了一个方法表的结构struct operation_func,这里面包含了一些函数指针,函数指针可以调用这些外设的读写方法。

每打开一个文件,就会为其创建一个方法集对象,而在struct file中,又包含了一些指针,其中就有一个可以指向这个方法集。

那么在进程创建的时候,进程有对应的文件描述符表,这个表就能指向这些文件,我们用户就提供系统调用,来访问这些文件。

所以从这个struct file往上,我们并不用关心底层访问的是什么东西,我们看到就是一切皆文件

image-20231111210255538

这里指针指向哪一个对象,就访问哪一个对象,这个不就是多态的逻辑吗?

相关文章:

Linux重定向

文章目录 1. 文件描述符分配规则2. 重定向接口dup2自定义shell重定向(补充) 3. 标准输出和标准错误4. 如何理解一切接文件 本章代码gitee地址&#xff1a;文件重定向 1. 文件描述符分配规则 文件描述符的分配规则是从0下标开始&#xff0c;寻址最小的没有使用的数组位置&#…...

Python之文件与文件夹操作及 pytest 测试习题

目录 1、文本文件读写基础。编写程序&#xff0c;在 当前目录下创建一个文本文件 test.txt&#xff0c;并向其中写入字符串 hello world。2、编写一个程序 demo.py&#xff0c;要求运行该程序后&#xff0c;生成 demo_new.py 文件&#xff0c;其中内容与demo.py 一样&#xff0…...

物联网:实现数据驱动决策,推动经济发展

开发物联网系统的意义主要体现在以下几个方面&#xff1a; 连接一切&#xff1a;物联网的目标是连接一切&#xff0c;将生活中的各种物理对象互联起来。通过物联网开发&#xff0c;我们可以实现各类设备的智能化&#xff0c;包括家居设备、交通工具、工业设备等。这将为人们提…...

Leetcode 2929. Distribute Candies Among Children II

Leetcode 2929. Distribute Candies Among Children II 1. 解题思路2. 代码实现 题目链接&#xff1a;2929. Distribute Candies Among Children II 1. 解题思路 这一题很惭愧&#xff0c;没能自力搞定&#xff0c;最后是看了大佬的思路之后才做出来的&#xff0c;唉…… 这…...

【面经】ES中分片是什么?副本是什么?

ES分片 分片是将一个索引切分为多个底层物理的Lucene索引&#xff0c;这些被切分出来的每个部分称为一个分片。 每个分片都是一个全功能且独立的索引&#xff0c;可由集群中的任何主机存储。 在创建索引时&#xff0c;用户可以指定其分片的数量。 默认情况下&#xff0c;每个索…...

【算法练习Day46】判断子序列不同的子序列

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 判断子序列不同的子序列总结…...

Java设计模式之访问者模式

目录 定义 结构 案例 优点 缺点 使用场景 扩展 分派 案例实现须知 动态分派 静态分派 双分派 定义 封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。 结构 访问者模式包含以下主要角色…...

PySide/PYQT如何用Qt Designer和代码来设置文字属性,如何设置文字颜色?

文章目录 📖 介绍 📖🏡 环境 🏡📒 实现方法 📒📝 Qt Designer设置📝 代码📖 介绍 📖 本人介绍如何使用Qt Designer/代码来设置字体属性(包含字体颜色) 🏡 环境 🏡 本文使用Pyside6来进行演示📒 实现方法 📒 📝 Qt Designer设置 首先打开Qt De…...

ubuntu 设置最大带宽

背景 近日做实验&#xff0c;需要限制一些机子的带宽以达到模拟的效果。在网上搜索了一阵子&#xff0c;结合自己实操的经验&#xff0c;潦草写下这篇文章&#xff0c;供自己与有需要的人参考。 环境&#xff1a; Ubuntu 22.04.1 LTS 安装 wondershaper 和 speedtest-cli w…...

如何在 Python 中执行 MySQL 结果限制和分页查询

Python MySQL 限制结果 限制结果数量 示例 1: 获取您自己的 Python 服务器 选择 “customers” 表中的前 5 条记录&#xff1a; import mysql.connectormydb mysql.connector.connect(host"localhost",user"您的用户名",password"您的密码"…...

Django配置文件,request,链接mysql方法,Orm简介

三板斧问题(views.py) HttpResponse # 返回的是字符串render # 渲染一个HTML静态文件&#xff0c;模板文件redirect # 重定向的 在视图文件中得视图函数必须要接收一个形参request&#xff0c;并且&#xff0c;视图函数也要有返回值&#xff…...

ubuntu下载各个版本chrome方法

Ubuntu/debian 在这里面找版本 https://unix.stackexchange.com/a/612981然后添充进去 http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_[HERE_THE_FULL_VERSION]_amd64.deb比如&#xff1a;https://dl.google.com/linux/chro…...

Http状态码502常见原因及排错思路(实战)

Http状态码502常见原因及排错思路 502表示Bad Gateway。当Nginx返回502错误时&#xff0c;通常表示Nginx作为代理服务器无法从上游服务器&#xff08;如&#xff1a;我们的后端服务器地址&#xff09;获取有效的响应。导致这种情况的原因有很多&#xff1a; 后端服务器故障ngin…...

国际阿里云:无法ping通ECS实例公网IP的排查方法!!!

无法ping通ECS实例的原因较多&#xff0c;您可以参考本文进行排查。 问题现象 本地客户端无法ping通目标ECS实例公网IP&#xff0c;例如&#xff1a; 本地客户端为Linux系统&#xff0c;ping目标ECS实例公网IP时无响应&#xff0c;如下所示&#xff1a; 本地客户端为Windo…...

Nginx缓存基础

1 nginx缓存的流程 客户端需要访问服务器的数据时&#xff0c;如果都直接向服务器发送请求&#xff0c;服务器接收过多的请求&#xff0c;压力会比较大&#xff0c;也比较耗时&#xff1b;而如果在nginx缓存一定的数据&#xff0c;使客户端向基于nginx的代理服务器发送请求&…...

【数据结构】Lambda

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈数据结构 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; Lambda表达式 1. 背景1.1 语法1.2 函…...

力扣labuladong——一刷day28

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣380. O(1) 时间插入、删除和获取随机元素二、力扣710. 黑名单中的随机数 前言 常数时间删除-查找数组中的任意元素&#xff0c;且随机访问概率一致 如果…...

2023年CCF非专业级别软件能力认证第二轮 (CSP-S)提高级C++语言试题

2023年CCF非专业级别软件能力认证第二轮 &#xff08;CSP-S&#xff09;提高级C语言试题 编程题第 1 题 问答题 密码锁&#xff08;lock&#xff09; 题目描述 小Y有一把五个拨圈的密码锁。如图所示&#xff0c;每个拨圈上是从0到9的数字。每个拨圈都是从0到9的循环&#xf…...

华为ensp:静态默认路由

静态路由 到r2 上的系统视图模式 下一跳为1.1.1.2 ip route-static 192.168.2.0 255.255.255.0 1.1.1.2 如果找2网段下一跳为1.1.1.2接口 默认路由 到r3上做的是默认路由 ip route-static 0.0.0.0 0 1.1.1.1 所有的流量去找1.1.1.1 查看效果 只要做完完整的路由就可…...

xss 通过秘籍

终极测试代码 <sCr<ScRiPt>IPT>OonN"\/(hrHRefEF)</sCr</ScRiPt>IPT> 第一关&#xff08;没有任何过滤&#xff09; 使用终极测试代码&#xff0c;查看源码 发现没有任何过滤&#xff0c;直接使用javascrupt中的alert弹框 <script>aler…...

Acunetix WVS 13实战:如何高效扫描企业网站漏洞并生成专业报告

Acunetix WVS 13企业级漏洞扫描实战&#xff1a;从策略优化到报告生成 在数字化转型浪潮中&#xff0c;企业网站作为对外展示和业务交互的核心窗口&#xff0c;其安全性直接关系到企业声誉和用户信任。一次成功的渗透测试可能发现数十个潜在漏洞&#xff0c;但如何系统化地识别…...

FPGA等精度频率计设计与实现

1. 等精度频率计的核心原理 等精度频率测量法之所以在FPGA设计中备受青睐&#xff0c;关键在于它巧妙地规避了传统方法的测量盲区。想象一下用两种不同的秒表测量短跑成绩&#xff1a;一个秒表由裁判手动控制&#xff08;软件闸门&#xff09;&#xff0c;另一个由运动员冲线瞬…...

Intv_AI_MK11 C++高性能计算集成指南:模型推理加速实践

Intv_AI_MK11 C高性能计算集成指南&#xff1a;模型推理加速实践 1. 为什么C开发者需要关注AI推理加速 在当今AI应用遍地开花的时代&#xff0c;C仍然是高性能计算领域的王者语言。当我们需要将AI模型集成到对延迟和吞吐量极其敏感的系统时——比如高频交易引擎、实时视频分析…...

GLM-OCR企业级多模态应用展示:结合视觉与文本理解复杂图表

GLM-OCR企业级多模态应用展示&#xff1a;结合视觉与文本理解复杂图表 你是不是也遇到过这种情况&#xff1f;拿到一份满是图表的业务报告&#xff0c;想快速提取里面的关键数据&#xff0c;却只能对着屏幕手动敲键盘&#xff0c;或者用传统的OCR工具识别出一堆零散的文字&…...

AI原生供应商尽调必查的9个代码层证据:从Dockerfile中CUDA版本锁定,到LangChain trace日志留存策略(附自动化扫描脚本)

第一章&#xff1a;AI原生软件研发供应商评估标准 2026奇点智能技术大会(https://ml-summit.org) AI原生软件研发已从概念验证阶段迈入规模化交付关键期&#xff0c;供应商能力不再仅由传统工程交付周期或代码行数衡量&#xff0c;而需聚焦于模型即服务&#xff08;MaaS&#…...

终极指南:如何用MixItUp实现动态内容的无缝插入与移除操作

终极指南&#xff1a;如何用MixItUp实现动态内容的无缝插入与移除操作 【免费下载链接】mixitup A high-performance, dependency-free library for animated filtering, sorting, insertion, removal and more 项目地址: https://gitcode.com/gh_mirrors/mi/mixitup Mi…...

探索正点原子7寸RGB液晶屏:AD20工程实战

适用于正点原子7寸RGB液晶屏资料&#xff0c;包含AD20完整工程最近&#xff0c;我入手了一块正点原子的7寸RGB液晶屏&#xff0c;搭配AD20开发板&#xff0c;想着能折腾出点有意思的东西。折腾的过程虽然有点坎坷&#xff0c;但收获还是挺多的&#xff0c;现在就来分享一下我的…...

第三节课总结

一、计算机中的单位1、比特位&#xff08;bit&#xff09;&#xff1a;一个比特位只能放一个二进制数据&#xff0c;要么0要么12.字节&#xff08;byte&#xff09;&#xff1a;一个字节 8个比特位1024byte 1KB1024KB 1MB1024MB 1GB1024GB 1T1024TB 1PB3.每一种数据类型都可…...

SenseBoxBLE库详解:phyphox协议下的Arduino BLE透传实践

1. SenseBoxBLE 库深度解析&#xff1a;面向嵌入式工程师的 BLE 数据透传实践指南1.1 库定位与工程价值SenseBoxBLE 是一个专为 senseBox 生态设计的轻量级 Arduino 兼容 BLE 通信库&#xff0c;其核心目标并非构建通用 BLE 协议栈&#xff0c;而是实现传感器数据到 phyphox 移…...

智微智能联合英特尔发布Gaudi2E四卡液冷工作站,赋能企业私有化AI算力

当前&#xff0c;AI技术正以前所未有的速度重塑千行百业。从大模型训练到智能体应用&#xff0c;从多模态内容生成到企业级代码开发&#xff0c;企业对AI计算的需求已不再局限于云端算力&#xff0c;而是愈发追求本地化部署、高性能输出与高安全保障。针对这一趋势&#xff0c;…...