【Linux】重定向,dup2

 2.重定向

2.1.输出重定向

1.输入重定项。

我们之前学习过的输出重定向就是,将我们本应该输出到显示器上的数据重定向输出到另一个文件中。那他的原理是什么了?

例如: 如果我们想让本应该输出到“显示器文件”的数据输出到log.txt文件当中,那么我们可以在打开log.txt文件之前将文件描述符为1的文件关闭,也就是将“显示器文件”关闭,这样一来,当我们后续打开log.txt文件时所分配到的文件描述符就是1。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
int main()
{
    close(1);
    // 打开文件
    int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
    {
        perror("open");
        exit(1);
    }
 
    // 打开成功
    printf("fd: %d\n", fd);
    printf("fd: %d\n", fd);
    printf("fd: %d\n", fd);
    printf("fd: %d\n", fd);
    fprintf(stdout, "hello fprintf\n");
    const char* s = "hello fwrite\n";
    fwrite(s, strlen(s), 1, stdout);
 
    fflush(stdout);
 
    // 关闭文件
    close(fd);   
    
    return 0;
}

通过上面的现象也可以看出,打印的数据没有到显示器上,而是到了磁盘的文件中,这是为什么呢?

        上面就说过,0、1、2默认是被打开的,对应的就要打开显示器,所以stdout的文件描述符就是1,所以C语言的接口fprintf认识的就是stdout或者说就是1,我们一开始就关闭了1号文件描述符,把数组下标为1的位置设置为NULL,然后打开了log.txt文件,此时1没有被占用,所以就把下标为1的位置填入log.txt的结构体的地址log.txt的文件描述符就是1了,但是上层的C语言函数认识的还是1,他们还是继续往1中写入,这样就不能打印到屏幕而是重定向到了文件中。

 

重定向的本质是在操作系统中更改fd对应的内容,上面演示的这就就叫做输出重定向。

2.2.输入重定向       

输入重定向就是,将我们本应该从一个键盘上读取数据,现在重定向为从另一个文件读取数据。

 

 比如说我们的fget函数是从标准输入读取数据,现在我们让它从log1.txt当中读取数据,我们在scanf读取数据之前close(0).这样键盘文件就被关闭,这样一样log1.txt的文件描述符就是0. 

int main()
{
    close(0);
    // 打开文件
    int fd = open("log.txt", O_RDONLY);
    if (fd < 0)
    {
        perror("open");
        exit(1);
    }
 
    printf("fd: %d\n", fd);
    char buffer[64];
    fgets(buffer, sizeof(buffer), stdin);
 
    printf("%s\n", buffer);
 
    // 关闭文件
    close(fd);
 
    return 0;
}

关闭了0号文件描述符,所以打卡的新文件的文件描述符就变成了0,然后读取了文件中的第一行数据。 

2.3.追加重定向

还有一种就是追加重定向,更改一下选项就行了。

int main()
{
    close(1);
    // 打开文件
    int fd = open("log.txt", O_WRONLY | O_APPEND | O_CREAT);
    if (fd < 0)
    {
        perror("open");
        exit(1);
    }
    printf("%d\n", fd);
    fprintf(stdout, "append success\n");
 
    fflush(stdout);
    
    // 关闭文件
    close(fd);
 
    return 0;
}

【注意】:“>”输出重定向修改的只是1号也就是stdout标准输出,所以尽管程序中有两行代码,一行向1号文件描述符中打印,另一行向2号文件描述符中打印,那么使用输出重定向只会使1号文件描述符重定向,2号还是打印到显示器上。

2.4.dup2

我们发现我们上面只能通过close关闭对应的文件描述符实习对应的输出重定向和输出重定向,那我们能不能不关闭呢?

要完成重定向我们只需对fd_array数组当中元素进行拷贝即可。

例如,我们若是将fd_array[3]当中的内容拷贝到fd_array[1]当中,因为C语言当中的stdout就是向文件描述符为1文件输出数据,那么此时我们就将输出重定向到了文件log.txt。而在linux当中就给我们提供了这个系统调用:

  • 函数功能: dup2会将fd_array[oldfd]的内容拷贝到fd_array[newfd]当中。
  • 函数返回值:调用成功返回0,失败返回-1

使用的过程中需要注意:

  1. 如果oldfd不是有效的文件描述符,则dup2调用失败,并且此时文件描述符为newfd的文件没有被关闭。
  2. 如果oldfd是一个有效的文件描述符,但是newfd和oldfd具有相同的值,则dup2不做任何操作,并返回newfd。

        只需要把想要重定向的文件在数组中拷贝过去,比如我想要输出重定向,重定向到某个文件,那么1就代表标准输出,所以就要改变1的指向,就把3的地址拷贝过去,这样1就指向了重定向的文件。 

输入重定向也是一样的,0是标准输入,就要从其他文件输入,就把其他文件的地址拷贝到0的位置。 

下面通过dup2演示一下前面的输出重定向:

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<sys/stat.h>
  4 #include<unistd.h>
  5 #include<fcntl.h>                                                                                                                               
  6 int main()
  7 {
  8   int fd=open("./log.txt",O_WRONLY|O_CREAT,0644);
  9    dup2(fd,1);
 10  printf("hello world\n");
 11  printf("hello world\n");
 12 
 13 }

2.5.重定向的本质 

重定向的本质,其实是在OS内部,更改fd对应的内容的指向!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring webflux基础核心技术

一、 用操作符转换响应式流 1 、 映射响应式流元素 转换序列的最自然方式是将每个元素映射到一个新值。 Flux 和 Mono 给出了 map 操作符&#xff0c;具有 map(Function<T&#xff0c;R>) 签名的方法可用于逐个处理元素。 当操作符将元素的类型从 T 转变为 R 时&#xf…

Linux虚拟机扩展磁盘空间

文章目录 在VM上进行扩展新的磁盘空间进入虚拟机将扩展的磁盘空间分配给对应的分区 VM 下的Linux虚拟机提示磁盘空间不足&#xff0c;需要对其进行磁盘扩容&#xff0c;主要有以下两步&#xff1a; 在VM上进行扩展新的磁盘空间 先关闭虚拟机在VM的虚拟机设置处进行硬盘扩展 …

电脑关机被阻止

1. winR输入regedit进入注册表 2. 选择HKEY_USERS-》.DEFAULT-》Control Panel-》Desktop 3. 右键DeskTop新建字符串值&#xff0c;命名为AutoEndTasks&#xff0c;数值设置为1

C++_入门

C入门 C发展历程 C的起源可以追溯到1979年&#xff0c;当时Bjarne Stroustrup(本贾尼斯特劳斯特卢普&#xff0c;这个翻译的名字不同的地⽅可能有差异)在贝尔实验室从事计算机科学和软件⼯程的研究工作。面对项目中复杂的软件开发任务&#xff0c;特别是模拟和操作系统的开发…

【SQL】DML、DDL、ROLLBACK 、COMMIT详解

DML DML&#xff08;Data Manipulation Language&#xff09;数据操作语言&#xff0c;是用于对数据库中的数据进行基本操作的一种编程语言。DML是数据库管理系统&#xff08;DBMS&#xff09;中的一个重要部分&#xff0c;它允许用户或应用程序对数据库中的数据进行增、删、改…

君方智能设计平台-数据对象升级框架设计

1.设计背景 由于文件存储基于流存储&#xff0c;目前处于快速开发阶段&#xff0c; 修改对象数据结构很频繁。对象数据结构的修改&#xff0c;会破坏文件的二进制内存结构&#xff0c;版本发布时导致一些已创建的项目文件不能正常打开。目前的解决方案是&#xff0c;先将文件导…

基于Python thinker GUI界面的股票评论数据及投资者情绪分析设计与实现

1.绪论 1.1背景介绍 Python 的 Tkinter 库提供了创建用户界面的工具&#xff0c;可以用来构建股票评论数据及投资者情绪分析的图形用户界面&#xff08;GUI&#xff09;。通过该界面&#xff0c;用户可以输入股票评论数据&#xff0c;然后通过情感分析等技术对评论进行情绪分析…

PX4 UM982 配合F9P Base 进行 RTK 定位

UM982是新兴的常见双天线GPS模块&#xff0c;支持双天线定向&#xff0c;RTK功能&#xff0c;PX4也引入了对其的支持&#xff0c;需要按需额外设置 官方手册号称直接用F9P做地面站&#xff0c;搭配QGC使用就能进行RTK定位 但是经过实践&#xff0c;发现这样是进不了RTK模式的…

解读网传《深圳IT圈⭕新解读八小时工作制》

网传深圳IT圈的新解读八小时工作制 工作时间安排&#xff1a; 10:00-12:0014:00-18:0019:00-21:00 初看&#xff1a;有惊喜 上午开始时间晚&#xff1a;相对于传统的9点开始&#xff0c;这种安排允许员工有更多的早晨时间&#xff0c;可以用来休息或处理个人事务。下午和晚上分…

应急响应总结

应急响应 日志 windows IIS 6.0 及更早版本&#xff1a; C:\WINDOWS\system32\LogFiles\W3SVC[SiteID]\ IIS 7.0 及更高版本&#xff1a; C:\inetpub\logs\LogFiles\W3SVC[SiteID]\ Apache HTTP Server C:\Program Files (x86)\Apache Group\Apache2\logs\ 或者 C:\Prog…

多态【C++】机制详解

文章目录 概念多态的定义和实现多态的构成虚函数虚函数的重写虚函数重写的两个例外协变(基类与派生类虚函数返回值类型不同) 注&#xff1a;很少遇到了解下就可以析构函数的重写(基类与派生类析构函数的名字不同) 两个新的关键字&#xff08;C11&#xff09;重载、覆盖(重写)、…

通过 PPPOE 将 linux 服务器作为本地局域网 IPv4 外网网关

将 linux 服务器作为本地外网网关&#xff0c;方便利用 Linux 生态中的各种网络工具&#xff0c;对流量进行自定义、精细化管理… 环境说明 拨号主机&#xff1a;CentOS 7.9, Linux Kernel 5.4.257 拨号软件: rp-pppoe-3.11-7.el7.x86_64初始化 1、升级系统到新的稳定内核&a…

【代码随想录】【算法训练营】【第65天】 [卡码94]城市间货物运输I

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 65&#xff0c;周四&#xff0c;继续ding~ [卡码94] 城市间货物运输I 题目描述 卡码94 城市间货物运输I 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 Be…

浅学三次握手

数据要完成传输&#xff0c;必须要建立连接。由于建立TCP连接的过程需要来回3次&#xff0c;所以&#xff0c;将这个过程形象的叫做三次握手。 结合上面的图来看更清楚。 先说三次握手吧&#xff0c;连接是后续数据传输的基础。就像我们打电话一样&#xff0c;必须保证我和对方…

DHCP原理及配置

目录 一、DHCP原理 DHCP介绍 DHCP工作原理 DHCP分配方式 工作原理 DHCP重新登录 DHCP优点 二、DHCP配置 一、DHCP原理 1 DHCP介绍 大家都知道&#xff0c;现在出门很多地方基本上都有WIFI&#xff0c;那么有没有想过这样一个问题&#xff0c;平时在家里都是“固定”的…

多媒体软件开发选择Animate软件还是Unity3D软件?

以下内容可能有一些片面&#xff0c;因为多媒体软件开发平台有很多&#xff0c;因为接触Animate和Unity3D比较多&#xff0c;所以这里仅对这两款进行分析&#xff01; Animate软件与Unity3D软件都是经常在多媒体展馆中用来制作互动展示内容的&#xff0c;对于这两种开发平台&a…

SpringBoot整合RedisTemplate的使用方法

文章目录 0.启动 Redis服务器1. 添加依赖2.配置 Redis 相关信息3. 创建配置类 RedisTemplate4. 使用 RedisTemplate5. 测试 0.启动 Redis服务器 打开 cmd &#xff0c; 输入 redis-server &#xff0c;启动 Redis 服务器。 1. 添加依赖 首先&#xff0c;在 pom.xml 中添加 Sp…

(word原件)软件系统详细需求设计书参考文档及软件文档大全

1引言 1.1编写目的 1.2项目背景 1.3参考材料 2系统总体设计 2.1整体架构 2.2整体功能架构 2.3整体技术架构 2.4设计目标 2.5.1总体原则 2.5.2实用性和先进性 2.5.3标准化、开放性、兼容性 2.5.4高可靠性、稳定性 2.5.5易用性 2.5.6灵活性和可扩展性 2.5.7经济性和投资保护 3系统…

秒懂设计模式--学习笔记(9)【结构型-装饰器模式】

目录 8、装饰器模式8.1 装饰器模式&#xff08;Decorator&#xff09;8.2 装修&#xff08;举例&#xff09;8.3 化妆&#xff08;示例&#xff09;8.4 化妆品的多样化8.5 装饰器8.6 自由嵌套8.7 装饰器模式的各角色定义8.8 装饰器模式 8、装饰器模式 8.1 装饰器模式&#xff…

GUI界面开发之tkinter(一)

Tkinter是一个内置的Python库&#xff0c;用于创建图形用户界面&#xff08;GUI&#xff09;。它提供了一组工具和小部件&#xff0c;用于创建窗口、对话框、按钮、菜单和其他GUI元素。 在本篇文章中&#xff0c;主要介绍了窗口等知识点。 大家好&#xff01;我是码银&#x1…