首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Linux系统#7】: 重定向(补充)

【Linux系统#7】: 重定向(补充)

作者头像
IsLand1314
发布2025-06-02 11:58:57
发布2025-06-02 11:58:57
4200
举报
文章被收录于专栏:学习之路学习之路

📃个人主页island1314

🔥个人专栏:Linux—登神长阶


引言

其实之前我们在这篇博客里面,已经提过了 重定向的 一些知识,这里是对 其做出的 一些补充学习,大家可以先看看之前的博客内容,再来学习这个

【Linux】基础 IO(文件描述符fd & 缓冲区 & 重定向)

1. 标准错误 -- 以C++中 cerr 为例

🚀 在 Linux 中,cerr 是 C++ 标准库中的一个输出流,用于输出错误消息。它是 isotream 头文件的一部分,具体定义在 std 命名空间下。以下是对 cerr 的详细说明:

1.1 基本概念
  • 无缓冲输出cerr 是一个无缓冲的输出流。这意味着当你向 cerr 输出数据时,数据会立即写入目标,而不会被缓冲。这对于错误信息的即时输出非常重要,因为你希望在发生错误时能够立即看到相关信息。
  • 标准错误流cerr 默认情况下连接到标准错误(stderr),这是一个用于输出错误信息的特殊输出流。在 Linux 中,标准错误和标准输出是两个不同的流,通常它们都连接到终端,但可以独立重定向。
1.2 使用 cerr

使用 cerr 输出错误信息的基本语法如下:

代码语言:javascript
复制
#include <iostream>
using namespace std;

int main()
{
    cerr << "Hello cerr" << endl;
    return 0;
}

运行如下:(错误信息 将立即输出到标准错误流。)

1.3 特性与行为
  • 线程安全:在多线程程序中,cerr 是线程安全的。这意味着多个线程可以安全地同时写入 cerr ,不会产生数据混乱。
  • 与 cout 区别:与 cout(标准输出流)相比,cerr 不会进行缓冲,因此更适合用于错误信息的输出。cerr 会对输出进行缓冲,可能导致信息的延迟显示。
1.4 cout 与 cerr 对比 🎐

还记得我们之前对输出重定向是怎么使用的嘛,如下:

举个例子,我们先编写如下程序 test.cc

代码语言:javascript
复制
#include <iostream>
#include <cstdio>

int main()
{
    std::cout << "Hello cout" << std::endl;
    printf("Hello printf\n");
}

然后输入指令 g++ test.cc,生成可执行文件 a.out

假如我们的代码里面有标准错误,修改如下:

代码语言:javascript
复制
#include <iostream>
#include <cstdio>

int main()
{
    // 1. 标准输出
    std::cout << "Hello cout" << std::endl;
    printf("Hello printf\n");
    // 2. 标准错误
    std::cerr << "Hello cerr" << std::endl;
    fprintf("Hello fprintf\n");
    return 0;
}

重定向如下:

解释:

虽然 1 和 2 指向同一个文件,但是这里只把log.txt 在OS内部对应的文件地址写到了1号里面,2号下标指向依然指向显示器文件,因此2仍然往显示器上面输出

造成上述结果的原因主要与标准输出和标准错误流的特性以及重定向机制有关。具体来说,以下几点解释了为什么 coutcerr 的输出表现不同:🔍

a. 输出流的区别
  • 标准输出(stdout)cout 是 C++ 的标准输出流,默认情况下,它连接到终端。它是缓冲的,意味着输出内容会先存储在内存中,直到缓冲区满或遇到换行符(如 endl),才会一次性写入终端。
  • 标准错误(stderr)cerr 是 C++ 的标准错误流,默认连接到终端。与 cout 不同,cerr 是无缓冲的,这意味着每次写入 cerr 时,内容会立即显示,无论缓冲区是否满。
b. 重定向的工作机制
  • 当你使用重定向符号 > 时,系统会将标准输出(stdout)重定向到指定的文件
  • 标准错误(stderr)流的重定向不会自动发生,除非明确指定。这意味着,尽管 cout 的输出被写入到 log.txtcerr 仍然会直接输出到终端。
c. 输出顺序
  • 在程序执行中,cout 的输出是先存储在缓冲区中,可能会在程序结束或调用 flush 时才写入文件,而 cerr 的输出立即显示。因此,终端上的错误信息会在文件内容输出后立刻可见。

这种机制确保了:

  • 正常的程序输出(cout )可以被重定向到文件,便于记录和查看。
  • 错误信息(cerr)能够迅速反馈给用户,不会因为输出重定向而延迟显示。这对于调试和错误处理非常重要。

如下:

2. 2>&1

对于上面代码,我们把输出和错误都重定向到文件中

上面我们是重定向到两个文件中,假如我们重定向到一个文件中呢,如下:

这里为啥最后只有标准错误的内容呢?

原因:由于重定向打开会先把文件清空,然后再进行打印,因此我们如果要让最后的打印把标准输出和标准错误的内容,都打印出来,需要做如下修改:

  • 追加式的重定向,避免清空之前内容

简化上面的写法 2&1

  • 2>&1:这是一个重要的部分,用于将标准错误(文件描述符 2)重定向到标准输出(文件描述符 1)。这意味着错误信息会被写入到 log.txt 中,而不是显示在终端
  • 这个重定向方法常用于日志记录,确保无论程序输出是正常还是错误信息,都可以被记录到同一个文件中,便于后续查看和分析

3. 练习

bash中,需要将脚本 demo.sh 的标准输出和标准错误输出重定向至文件demo.log,以下哪些用法是正确的 [多选]

正确答案: A B C D

A. bash demo.sh &>demo.log B. bash demo.sh >&demo.log C. bash demo.sh >demo.log 2>&1 D. bash demo.sh 2>demo.log 1>demo.log

分析: 在命令的重定向中, >表示重定向,0 表示标准输入,1 表示标准输出,2 表示标准错误 如果需要将标准输出和标准错误输出重定向至文件demo.log; 比较典型的方式是:bash demo.sh 1>demo.log 2>&1

  • 先将标准输出重定向到demo.log文件,然后将标准错误重定向到标准输出(这时候的标准输出已经是指向文件了,所以也就是将标准错误重定向到文件)

A、command &> file 表示将标准输出stdout和标准错误输出stderr重定向至指定的文件file中。 B、与A的选项功能雷同 C、一个十分典型的写法,将标准输出和标准错误都重定向到文件, >demo.log是一种把前面的标准输出 1 忽略掉的写法 D、比较直观的一种写法,给我们直观的将标准输入和标准错误分别重定向到文件


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-04-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 1. 标准错误 -- 以C++中 cerr 为例
    • 1.1 基本概念
    • 1.2 使用 cerr
    • 1.3 特性与行为
    • 1.4 cout 与 cerr 对比 🎐
      • a. 输出流的区别
      • b. 重定向的工作机制
      • c. 输出顺序
  • 2. 2>&1
  • 3. 练习
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档