要将stderr和stdout合并到stdout流中,我们将其附加到命令中:

2>&1

例如,查看编译g++main.cpp时的前几个错误:

g++ main.cpp 2>&1 | head

2>&1的详细含义是什么?


当前回答

如果系统上不存在/foo,而/tmp确实存在…

$ ls -l /tmp /foo

将打印/tmp的内容并为/foo打印错误消息

$ ls -l /tmp /foo > /dev/null

将/tmp的内容发送到/dev/null并为/foo打印错误消息

$ ls -l /tmp /foo 1> /dev/null

将完全相同(注意1)

$ ls -l /tmp /foo 2> /dev/null

将打印/tmp的内容并将错误消息发送到/dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

将向/dev/null发送列表和错误消息

$ ls -l /tmp /foo > /dev/null 2> &1

是速记

其他回答

注意,1>&2不能与2>&1互换使用。

假设您的命令依赖于管道,例如:docker日志1b3e97c49e39 2>&1|grep“一些日志”grepping将在stderr和stdout之间发生,因为stderr基本上被合并到stdout中。

但是,如果您尝试:docker日志1b3e97c49e39 1>&2|grep“一些日志”,grepping根本不会在任何地方搜索,因为Unix管道通过连接stdout|stdin来连接进程,而在第二种情况下,stdout被重定向到stderr,Unix管道对此没有兴趣。

0表示输入,1表示标准输出,2表示标准错误。

一个提示:somecmd>1.text 2>&1是正确的,而somecmd2>&1>1.text完全错误,没有效果!

这些数字表示文件描述符(fd)。

零是标准输入一个是标准输出二是标准错误

2> &1将fd 2重定向为1。

如果程序使用任何数量的文件描述符,这都适用。

如果忘记了,可以查看/usr/include/unistd.h:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

也就是说,我已经编写了C工具,这些工具使用非标准文件描述符进行自定义日志记录,因此除非将其重定向到文件或其他文件,否则您不会看到它。

如果系统上不存在/foo,而/tmp确实存在…

$ ls -l /tmp /foo

将打印/tmp的内容并为/foo打印错误消息

$ ls -l /tmp /foo > /dev/null

将/tmp的内容发送到/dev/null并为/foo打印错误消息

$ ls -l /tmp /foo 1> /dev/null

将完全相同(注意1)

$ ls -l /tmp /foo 2> /dev/null

将打印/tmp的内容并将错误消息发送到/dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

将向/dev/null发送列表和错误消息

$ ls -l /tmp /foo > /dev/null 2> &1

是速记

回答您的问题:它接受任何错误输出(通常发送到stderr)并将其写入标准输出(stdout)。

例如,当您需要为所有输出分页时,这对于“more”很有用。有些程序喜欢将使用信息打印到stderr中。

帮助你记住

1=标准输出(程序打印正常输出)2=标准错误(程序打印错误)

“2>&1”只是将发送到stderr的所有内容指向stdout。

我还建议阅读这篇关于错误重定向的文章,其中详细介绍了这个主题。