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

【Linux】Linux中重定向 及 dup2 详细讲解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

目录

一、重定向的本质问题

传统重定向的缺陷

二、dup2系统调用:完美解决方案

函数原型

核心功能

参数解析

三、dup2工作原理图解

四、基础应用:输出重定向

1. 标准输出重定向到文件

2. 标准错误重定向到文件

五、高级应用场景

1. 输入重定向

2. 管道重定向(父子进程通信)

3. 临时重定向与恢复

六、dup2 vs 传统重定向对比

七、扩展知识:dup与dup3


提示:以下是本篇文章正文内容,下面案例可供参考

一、重定向的本质问题

传统重定向的缺陷

课件中展示的经典重定向方法:

 close(1); // 关闭标准输出
int fd = open("log.txt", O_WRONLY|O_CREAT, 0644);
printf("This goes to file"); // 输出到文件

存在三大问题:

  1. 竞态条件:关闭和打开之间可能有其他线程操作文件描述符

  2. 资源泄漏风险:可能意外关闭重要描述符

  3. 不可恢复:无法轻松恢复原始状态

二、dup2系统调用:完美解决方案

函数原型
 #include <unistd.h>
int dup2(int oldfd, int newfd);
核心功能
  • 复制oldfd文件描述符到newfd

  • 如果newfd已打开,自动关闭

  • 原子操作:避免竞态条件

  • 返回新的文件描述符(即newfd

参数解析
参数含义特殊说明
oldfd源文件描述符(需保持打开)必须为有效打开的文件描述符
newfd目标文件描述符(将被替换)若等于oldfd,直接返回newfd

三、dup2工作原理图解

操作过程

  1. 检查oldfd有效性

  2. newfd已打开,静默关闭

  3. 复制oldfdnewfd位置

  4. 返回newfd(失败时返回-1)

四、基础应用:输出重定向

1. 标准输出重定向到文件

#include <fcntl.h>
#include <unistd.h>int main() {int file_fd = open("output.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);if(file_fd < 0) {perror("open failed");return 1;}// 关键操作:重定向stdout到文件dup2(file_fd, STDOUT_FILENO);// 可安全关闭原文件描述符close(file_fd);// 所有标准输出将写入文件printf("This goes to output.log\n");fprintf(stdout, "This also goes to file\n");return 0;
}
2. 标准错误重定向到文件

int err_fd = open("errors.log", O_WRONLY|O_CREAT|O_APPEND, 0644);
dup2(err_fd, STDERR_FILENO);
close(err_fd);fprintf(stderr, "Error message logged\n");

五、高级应用场景

1. 输入重定向

int in_fd = open("input.dat", O_RDONLY);
if(in_fd < 0) {perror("open input failed");exit(1);
}dup2(in_fd, STDIN_FILENO);
close(in_fd);// 从文件读取而非键盘
char buf[1024];
fgets(buf, sizeof(buf), stdin);
2. 管道重定向(父子进程通信)

int pipefd[2];
pipe(pipefd);  // 创建管道pid_t pid = fork();
if(pid == 0) { // 子进程close(pipefd[0]);  // 关闭读端dup2(pipefd[1], STDOUT_FILENO); // 重定向输出到管道close(pipefd[1]);execlp("ls", "ls", "-l", NULL);
} else { // 父进程close(pipefd[1]);  // 关闭写端dup2(pipefd[0], STDIN_FILENO); // 重定向输入从管道close(pipefd[0]);char buffer[4096];while(fgets(buffer, sizeof(buffer), stdin)) {// 处理ls输出}
}
3. 临时重定向与恢复

// 保存原始stdout
int saved_stdout = dup(STDOUT_FILENO);// 临时重定向到文件
int tmp_fd = open("temp.out", O_WRONLY|O_CREAT, 0644);
dup2(tmp_fd, STDOUT_FILENO);
close(tmp_fd);printf("This is in temp file");// 恢复原始stdout
dup2(saved_stdout, STDOUT_FILENO);
close(saved_stdout);printf("Back to console output");

六、dup2 vs 传统重定向对比

特性dup2实现手动关闭/打开实现
原子性✅ 单次系统调用❌ 多个步骤
竞态条件✅ 无风险❌ 高风险
错误处理✅ 简单(单次检查)❌ 需要多步骤检查
资源泄漏风险✅ 自动关闭目标描述符❌ 需手动管理
描述符保留✅ 保留原描述符❌ 需要额外处理
恢复原始状态✅ 容易(配合dup)❌ 困难

七、扩展知识:dup与dup3

  1. dup基础版本

    int new_fd = dup(old_fd); // 自动分配最小可用fd

  2. dup3增强版

    dup3(oldfd, newfd, O_CLOEXEC); // 带标志位的复制

dup2作为Linux系统编程的核心工具,完美解决了文件描述符重定向的各种痛点。掌握其原理和技巧,将使你的I/O操作更安全、更高效,为管道、守护进程等高级特性打下坚实基础。

http://www.dtcms.com/a/288351.html

相关文章:

  • Stream API
  • 2023 年 5 月青少年软编等考 C 语言八级真题解析
  • 本地安装部署Unstructured-api
  • ADC选型设计
  • SpringBoot项目打包加部署方案
  • Datawhale 7月学习
  • SCSAI工业智能体的核心特征
  • Xss-labs 1-8以及利用python自动sq8注入
  • linux cpu频率和AVS调压等级
  • 板子 5.29--7.19
  • 函数式编程和命令式编程
  • Python爬虫实战:研究psd-tools库相关技术
  • UI 程序退出卡顿问题分析:从真实案例深入理解退出清理路径负载问题
  • 【工具变量】地级市城市包容性绿色增长数据(2011-2023年)
  • vue3使用KeepAlive组件及一些注意事项
  • [spring6: Advice Advisor Advised]-快速理解
  • 基于深度学习的火灾智能检测系统设计与实现
  • 零基础学习性能测试第二章-linux服务器监控:网络iftop
  • HTTP与HTTPS技术细节及TLS密钥交换与证书校验全流程
  • 马走日题解
  • LeetCode Hot100【7. 整数反转】
  • MyBatis动态SQL全解析:五大核心标签实战指南
  • [每日随题11] 贪心 - 数学 - 区间DP
  • 路由器内部电子元器件详解
  • C++数据结构————二叉树
  • 模电基础-电压和电阻
  • RISC采用的3种流水技术的功能和区别分析
  • 【官方】OneCode 3.0 核心技术白皮书:注解驱动、可视编码与 AI 融合
  • 相角补偿全通滤波器设计:相位均衡(0~350Hz,15°超前)
  • 关于如何同步开发板的时间和现在一样: