Linux重定向:深入理解与实践

 

                                                           🎬慕斯主页修仙—别有洞天 

                                                         ♈️今日夜电波:晴る—ヨルシカ

                                                                0:20━━━━━━️💟──────── 4:30
                                                                    🔄   ◀️   ⏸   ▶️    ☰  

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


 

目录

引入

文件描述符的分配规则

重定向理解

什么是重定向?

输出重定向

输入重定向

追加重定向

dup2

重新理解‘输入’和‘输出’重定向

完整的重定向格式

标准输出重定向

标准错误重定向

标准输出以及标准错误重定向同一文件


引入

文件描述符的分配规则

        在Linux系统中,文件描述符是一个数字,这个数字是用于表示打开的文件、管道和网络连接等进程所操作对象的标识符。文件描述符的分配规则遵循最小分配原则,也就是寻找未被占用的最小的文件描述符来使用。

        在Linux进程中,默认会有三个已经打开的文件描述符,对应的是标准输入(0)、标准输出(1)和标准错误(2)。这三个文件描述符分别对应键盘、显示器和打印机等物理设备。

        当我们需要打开新的文件时,系统会根据最小分配原则找到下一个可用的文件描述符进行分配。一般来说,新打开的文件会占用文件描述符3(如果0、1、2尚未被占用),接着是文件描述符4,以此类推。特别的,如果0、1或2已被关闭,那么新打开的文件的文件描述符可能会被赋值为0或1或2。

        需要注意的是,虽然文件描述符是连续分配且依次增大的,但它们的起始值并不从0开始,而是从3开始。

        🌰

        在学习完Linux下的系统文件操作后,我们都知道Linux下一切皆文件,我们可以对文件进行打开、读、写、关闭等操作。而系统默认会帮我们打开三个文件,分别为标准输入、标准输出和标准出错处理,即:stdin、stdout、stderr。这三个文件分别对应文件描述符0、1、2。那么如果我们关闭了其中的一个文件,再额外打开个新的文件会这么样呢?如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{umask(0);close(1);//关闭输出流int fd = open(FI, O_WRONLY | O_CREAT | O_TRUNC, 0666);printf("hello!\n");printf("hello!\n");printf("hello!\n");printf("hello!\n");printf("hello!\n");printf("hello!\n");printf("hello!\n");printf("my fd is %d\n",fd); return 0;
}

        对上述代码的情况可见:我们关闭了输出流的文件,新打开了一个文件,而使用printf进行打印操作。需要注意的是:printf、scanf都是默认的输入输出流,也就是说他们是按照stdin、stdout来进行对应的操作的。而此时printf非但没有把字符打印到显示器上反而打印到了新开的那个文件里,并且对应的文件描述符居然是1!这就说明了新开文件的文件描述符是遵守有空就补、从小到大使用的规律。

        大致的操作如下:

        对此,这也引出了我们重定向的概念—重定向是一种改变标准输入或输出默认执行方式的操作,无需大量的鼠标和键盘操作就可以完成数据的转移。

重定向理解

什么是重定向?

        在Linux系统中,重定向的本质是修改原来默认的执行方式,对系统命令的执行过程进行重新定义。它主要涉及两个方面:输入重定向和输出重定向。

  • 输入重定向:指的是将一个文件的内容导入到命令中作为输入数据。这种方式可以使得命令的执行不再依赖键盘的输入,而是读取来自指定文件的数据,从而提高了效率和便捷性。
  • 输出重定向:指的是将命令的执行结果保存到文件中,而不是直接显示在显示器上。这种方式可以将命令的输出信息保存下来,以供后续分析和使用,避免了信息的丢失。

        说大白话就是:修改特性文件fd下标的内容,上层fd不变,底层fd指向的内容在改变

输出重定向

        我们通过关闭文件描述符1或者2,然后打开一个新的文件使得通过printf输出的内容输出到fi.txt文件中。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{umask(0);close(1);//关闭输出流int fd = open(FI, O_WRONLY | O_CREAT | O_TRUNC, 0666);printf("output redirection!\n");printf("output redirection!\n");printf("output redirection!\n");printf("my fd is %d\n",fd); return 0;
}

输入重定向

        我们通过关闭文件描述符0,然后打开一个新的文件通过scanf从fi.txt中输入内容,然后再通过printf输出到显示器上。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{umask(0);close(1);//关闭输入流int fd = open(FI, O_RDONLY , 0666);char *st;scanf("%s",st);printf("%s\n",st);scanf("%s",st);printf("%s\n",st);scanf("%s",st);printf("%s\n",st);printf("my fd is %d\n",fd); return 0;
}

追加重定向

        本质还是和输出重定向一样关闭文件描述符1或者2,但是需要注意的是我们更改了打开文件的操作,把清空操作改为了追加操作。 O_TRUNC -> O_APPEND

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{umask(0);close(1);//关闭输出流int fd = open(FI, O_WRONLY | O_CREAT | O_APPEND,  0666);printf("append redirection!\n");printf("append redirection!\n");   printf("append redirection!\n");printf("my fd is %d\n",fd); return 0;
}

dup2

        dup2函数是Unix/Linux系统中的一个系统调用函数,作用是复制文件描述符,并将其指定为新的文件描述符。其具体功能是将一个已存在的文件描述符复制到另一个新的文件描述符上,并且可以自定义新文件描述符的编号。系统中的手册如下:

        这个函数在C语言中常用于实现输入输出重定向。例如,可以先使用open()函数打开需要重定向的文件,然后使用dup2()函数将指定的文件描述符复制到新的文件描述符。这样就可以改变一个进程的标准输入、标准输出和标准错误输出的文件描述符指向,进而实现重定向的功能。

        dup2函数的原型为 int dup2 (int oldfd, int newfd); 其中,oldfd参数表示要被复制的文件描述符,newfd参数表示新的文件描述符。如果newfd已经打开,则先将其关闭。如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。

        需要注意的是:dup2函数是dup()函数的“升级版“,因为与dup()只能复制一次不同,dup2可以无限次复制文件描述符。此外,如果复制成功,dup2函数会返回最小的尚未被使用过的文件描述符。

 

        🌰

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{umask(0);int fd = open(FI, O_WRONLY | O_CREAT | O_APPEND,  0666);dup2(fd,1);printf("append redirection!\n");printf("append redirection!\n");   printf("append redirection!\n");printf("my fd is %d\n",fd); close(fd);return 0;
}

重新理解‘输入’和‘输出’重定向

        在Linux中,>、>>和<、<<是重定向操作符,用于将命令的输出或输入重定向到文件或管道。

        - >:将命令的标准输出重定向到一个文件中,如果该文件不存在则创建它,如果存在则覆盖原有内容。例如:ls > file.txt 会将ls命令的输出保存到file.txt文件中。

        - >>:将命令的标准输出追加到一个文件中,如果该文件不存在则创建它。例如:ls >> file.txt 会将ls命令的输出追加到file.txt文件中。

        - <:将一个文件的内容作为命令的标准输入。例如:sort < file.txt 会将file.txt文件的内容作为sort命令的输入。

        - <<:将多行文本作为命令的标准输入。例如:echo -e "line1 line2 line3" | cat << EOF 会将EOF标记之间的文本作为cat命令的输入。

        通过上面我们对于重定向的理解,我们也从本质上理解了重定向实际上做的是什么操作,即:修改底层fd的指向。接下来我们进一步学习对于输入和输出的重定向!

完整的重定向格式

        实际上,完整的重定向格式如下:

命令 fd>/>>/</<< 命令

        🌰

标准输出重定向

标准错误重定向

标准输出以及标准错误重定向同一文件

 


                         感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                        给个三连再走嘛~  

 

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

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

相关文章

【cucumber】cluecumber-report-plugin生成测试报告

cluecumber为生成测试报告的第三方插件&#xff0c;可以生成html测报&#xff0c;该测报生成需以本地json测报的生成为基础。 所以需要在测试开始主文件标签CucumberOptions中&#xff0c;写入生成json报告。 2. pom xml文件中加入插件 <!-- 根据 cucumber json文件 美化测…

【llm 微调code-llama 训练自己的数据集 一个小案例】

这也是一个通用的方案&#xff0c;使用peft微调LLM。 准备自己的数据集 根据情况改就行了&#xff0c;jsonl格式&#xff0c;三个字段&#xff1a;context, answer, question import pandas as pd import random import jsondata pd.read_csv(dataset.csv) train_data data…

【开源】基于JAVA的CRM客户管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 用例设计3.2 E-R 图设计3.3 数据库设计3.3.1 客户表3.3.2 商品表3.3.3 客户跟踪表3.3.4 客户消费表3.3.5 系统角色表 四、系统展示五、核心代码5.1 查询客户5.2 新增客户跟踪记录5.3 新增客户消费订单5.4 查…

复现PointNet++(语义分割网络):Windows + PyTorch + S3DIS语义分割 + 代码

一、平台 Windows 10 GPU RTX 3090 CUDA 11.1 cudnn 8.9.6 Python 3.9 Torch 1.9.1 cu111 所用的原始代码&#xff1a;https://github.com/yanx27/Pointnet_Pointnet2_pytorch 二、数据 Stanford3dDataset_v1.2_Aligned_Version 三、代码 分享给有需要的人&#xf…

操作系统-操作系统体系结构(内核 外核 模块化 宏内核 微内核 分层结构)

文章目录 大内核与微内核总览操作系统的内核大内核与微内核的性能差异小结 分层结构与模块化与外核总览分层结构模块化宏内核&#xff0c;微内核外核 大内核与微内核 总览 操作系统的内核 操作系统的核心功能在内核中 对于与硬件关联程度的程序 由于进程管理&#xff0c;存…

L1-067 洛希极限(Java)

科幻电影《流浪地球》中一个重要的情节是地球距离木星太近时&#xff0c;大气开始被木星吸走&#xff0c;而随着不断接近地木“刚体洛希极限”&#xff0c;地球面临被彻底撕碎的危险。但实际上&#xff0c;这个计算是错误的。 洛希极限&#xff08;Roche limit&#xff09;是一…

OpenMV入门

1. 什么是OpenMV OpenMV 是一个开源&#xff0c;低成本&#xff0c;功能强大的 机器视觉模块。 OpenMV上的机器视觉算法包括 寻找色块、人脸检测、眼球跟踪、边缘检测、标志跟踪 等。 以STM32F427CPU为核心&#xff0c;集成了OV7725摄像头芯片&#xff0c;在小巧的硬件…

小程序学习-19

Vant Weapp - 轻量、可靠的小程序 UI 组件库 ​​​​​ Vant Weapp - 轻量、可靠的小程序 UI 组件库 安装出现问题&#xff1a;rollbackFailedOptional: verb npm-session 53699a8e64f465b9 解决办法&#xff1a;http://t.csdnimg.cn/rGUbe Vant Weapp - 轻量、可靠的小程序…

海外媒体发稿:满足要求的二十个爆款文案的中文标题-华媒舍

爆款文案是指在营销和推广方面非常受欢迎和成功的文案。它们能够吸引读者的眼球&#xff0c;引发浏览者的兴趣&#xff0c;最终促使他们采取行动。本文将介绍二十个满足要求的爆款文案的中文标题&#xff0c;并对每个标题进行拆解和描述。 1. "XX 绝对不能错过的十大技巧…

RHEL - 更新升级软件或系统

《OpenShift / RHEL / DevSecOps 汇总目录》 文章目录 小版本软件更新yum update 和 yum upgrade 的区别升级软件和升级系统检查软件包是否可升级指定升级软件使用的发行版本方法1方法2方法3方法4 查看软件升级类型更新升级指定的 RHSA/RHBA/RHEA更新升级指定的 CVE更新升级指定…

第36集《佛法修学概要》

请大家打开讲义第九十六面&#xff0c;我们讲到禅定的修学方便。 在我们发了菩提心&#xff0c;安住菩萨种性以后&#xff0c;我们开始操作六度的法门。六度的法门&#xff0c;它有两个不同的差别的内容&#xff0c;一种是成就我们的善业力&#xff0c;另外一种&#xff0c;是…

【Linux】第三十一站:管道的一些应用

文章目录 一、我们之前的|(竖划线)管道二、自定义shell三、使用管道实现一个简易的进程池1.详解2.代码3.一个小bug4.最终代码 一、我们之前的|(竖划线)管道 cat test.txt | head -10 | tail -5如上代码所示&#xff0c;是我们之前所用的管道 我们拿下面这个举个例子 当我们用…