我想知道以下两个命令之间的区别
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)消息并且打印在控制台上