2>&1 > output.log 和 2>&1 | 之间的区别tee输出.log

2>&1 > output.log 和 2>&1 | 之间的区别tee输出.log

我想知道以下两个命令之间的区别

2>&1 > output.log 

2>&1 | tee output.log

我看到我的一位同事使用第二个选项进行重定向。我知道 2>&1 的作用,我唯一的问题是使用 tee 的目的是什么,可以使用简单的重定向 ">" 运算符?

答案1

分别看两个命令:

utility 2>&1 >output.log 

在这里,由于重定向是以从左到右的方式处理的,因此标准错误流将首先被重定向到标准输出流所在的位置(可能是控制台),然后标准输出流将被重定向到文件。标准错误流将不是被重定向到该文件。

这样做的明显效果是,您可以在屏幕上看到标准错误生成的内容以及文件中标准输出生成的内容。

utility 2>&1 | tee output.log

在这里,您将标准错误重定向到与标准输出流相同的位置。这意味着两个都流将作为单个混合输出流通过管道传输到tee实用程序,并且该标准输出数据将通过tee.数据还将tee在控制台中再现(这就是它tee的作用,它复制数据流)。

使用其中哪一种取决于您想要实现的目标。

请注意,您将无法仅使用>( 如 中那样重现第二个管道的效果,这将通过首先将标准输出重定向到文件,然后将标准错误重定向到标准输出所在的位置来将标准utility >output.log 2>&1输出和错误保存在文件中output.log现在去)。您需要使用它tee来获取控制台和输出文件中的数据。


补充笔记:

可见的第一个命令的效果,

utility 2>&1 >output.log 

会是一样的

utility >output.log

即,标准输出转到文件,标准错误转到控制台。

如果在上述每个命令的末尾添加进一步的处理步骤,则会有很大的不同:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

在第一个管道中,more_stuff将获得最初的标准错误流作为utility其标准输入数据,而在第二个管道中,由于它只是通过管道发送的结果标准输出流,因此more_stuff管道的部分将什么也得不到读取其标准输入。

答案2

第一个命令将执行另一个任务:

2>&1 > output.log 

旧的 STDOUT 将被保存(复制)在 STDERR 中,然后 STDOUT 将被重定向到文件。

因此,stdout 将转到文件,stderr 将转到控制台。

并且在

 2>&1 | tee output.log

两个流都将被重定向到 tee。 Tee 会将任何输入复制到其标准输出(在您的情况下为控制台)和文件 ( output.log)。

第一还有另一种形式:

    > output.log  2>&1

这会将 STDOUT 和 STDERR 重定向到该文件。

答案3

前者仅输出到文件。第二个将两者输出到文件到屏幕上。

答案4

让我们先看一些示例代码:

#include <stdio.h>
main() 
{
// message 1, on stdout (using  printf)
printf("%s",          "message 1, on stdout (using  printf)\n");

// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");

// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}

让我们比较一下结果:
./helloerror
+ 文件:没有消息;控制台:消息1、2、3;

./helloerror >error.txt
+ 文件:消息1,2;控制台:消息3;

./helloerror 2>&1 >error.txt
+ 文件:消息1,2;控制台:消息3;
+ 与 ./helloerror >error.txt 相同

./helloerror >error.txt 2>&1
+ 文件:消息 3,1,2;控制台:没有消息;
+ 注意顺序是 3 先,然后是 1,然后是 2

./helloerror | tee error.txt 2>&1
+ 文件:消息1,2;控制台:消息 3,1,2;
+ 注意顺序是 3 先,然后是 1,然后是 2

./helloerror 2>&1 | tee error.txt
+ 文件:消息 3,1,2;控制台:消息 3,1,2;

使用方法:
./helloerror >error.txt 2>&1
-> 如果想要文件中的所有(stdout+stderr)消息,但是未固定在控制台上

./helloerror 2>&1 | tee error.txt
-> 如果想要文件中的所有(stdout+stderr)消息并且打印在控制台上

相关内容