我想知道以下两个命令之间的区别
2>&1 > output.log
和
2>&1 | tee output.log
我看到一位同事使用第二个选项进行重定向。我知道2>&1是什么,我唯一的问题是在可以使用简单重定向“>”运算符的地方使用tee的目的是什么?
我想知道以下两个命令之间的区别
2>&1 > output.log
和
2>&1 | tee output.log
我看到一位同事使用第二个选项进行重定向。我知道2>&1是什么,我唯一的问题是在可以使用简单重定向“>”运算符的地方使用tee的目的是什么?
Answers:
分别查看两个命令:
utility 2>&1 >output.log
在这里,由于重定向是以从左到右的方式处理的,因此标准错误流将首先被重定向到标准输出流去往的任何地方(可能到控制台),然后标准输出流将被重定向到文件。标准错误流不会重定向到该文件。
可见的效果是,您可以在屏幕上获得标准错误产生的结果以及文件中标准输出产生的结果。
utility 2>&1 | tee output.log
在这里,您将标准错误重定向到与标准输出流相同的位置。这意味着两个流都将tee
作为单个混合的输出流通过管道传输到实用程序,并且该标准输出数据将通过保存到给定文件tee
。数据将另外tee
在控制台中复制(这是这样tee
做的,它复制数据流)。
使用哪种方法取决于您想要实现的目标。
请注意,您将无法使用just来重现第二个管道的效果>
(如中所示utility >output.log 2>&1
,这将在文件中保存标准输出和错误)。您将需要使用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
该管道的任何部分都将一无所获读取其标准输入。
utility 2>&1 > output.log | more_stuff
和utility >ouput.log
| 的例子 more_stuff , is the difference that
more_stuff`是否将标准错误输出到控制台作为输入more_stuff
?由于在第二个示例中,没有任何输出到控制台,因此基本上没有输入到more_stuff
?。如果是的话,这是不清楚的,因为上一段您会注意到标准输出进入文件,而标准错误进入控制台。
more_stuff
将接收utility
最初发送到其错误流的内容(但将其重定向到标准输出)。不是因为它more_stuff
不出现在控制台上,而是因为它将进入标准输出流。在第二个命令中,什么都没more_stuff
收到,因为管道的左侧没有标准输出。来自的错误流仍将在第二个命令中最终出现在控制台上。utility
utility > output.log | more_stuff
从标准错误的角度来看,该命令不会在标准输出流中导致输出?
请务必阅读本答案的评论 - derobert。
原始答案
2>&1 >output.log
意味着首先开始将所有文件句柄2的东西(标准错误)发送到文件句柄1(标准输出),然后将其发送到文件output.log
。换句话说,将标准错误和标准输出发送到日志文件。
2>&1 | tee output.log
与2>&1
位相同,它将标准输出和标准误差组合到标准输出流上。它然后通过管道穿过tee
这将它的标准输入发送到其标准输出(如程序cat
),并也给该文件。因此,它将两个流(错误和输出)结合在一起,然后将其输出到终端和文件。
底线是,所述第一发送stderr
/ stdout
到该文件,而第二个将其发送到两个文件和标准输出(这是可能的终端,除非你已重定向标准输出的另一构建体内部)。
我提到最后一种可能性,因为您可以拥有以下内容:
(echo hello | tee xyzzy.txt) >plugh.txt
终端上什么都没有结束。
cat /doesnotexist 2>&1 >output.txt
-您将看到cat: /doesnotexist: No such file or directory
显示在终端上,并且output.txt是一个空文件。优先顺序和结束顺序在起作用:(2>&1
将fd1 从当前 fd1 复制到fd2 ),然后>output.txt
(将fd1重定向到output.txt,而不更改其他任何内容)。2>&1 |
不同的原因是由于优先顺序:|
before >
。
前者仅输出到文件。第二个输出到文件和屏幕。
我们先来看一些示例代码:
#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)消息记录在文件中并打印在控制台上
以下是总结Unix输出流的文章:http : //www.devcodenote.com/2015/04/unix-output-streams.html
帖子摘录:
有3个标准输出流:
STDIN - Standard Input - Writes from an input device to the program
STDOUT - Standard Output - Writes program output to screen unless specified otherwise.
STDERR - Standard Error Output - Writes error messages. Also printed to the screen unless specified otherwise.
utility 2>&1 | tee output.log
,您是说由于1被定向到tee,2也被定向。由于tee复制了流,所以输出既显示在控制台上又写入了文件?因此,utility 2>&1 > output.log
和之间的区别utility 2>&1 | tee output.log
是tee
因为它复制了视频流,对吗?