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

2>&1

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

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

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


当前回答

该构造将标准错误流(stderr)发送到标准输出(stdout)的当前位置——其他答案似乎忽略了这个货币问题。

您可以使用此方法将任何输出句柄重定向到另一个,但它最常用于将stdout和stderr流引导到单个流中进行处理。

例如:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

请注意,最后一个命令不会将stderr重定向到outfile2,而是将其重定向到遇到参数时的stdout(outfile1),然后将stdout重定向到outile2。

这允许一些相当复杂的诡计。

其他回答

2> &1是POSIX外壳构造。以下是逐个令牌的细分:


2:“标准错误”输出文件描述符。

>&:复制输出文件描述符运算符(输出重定向运算符>的变体)。给定[x]>&[y],由x表示的文件描述符被制作为输出文件描述符y的副本。

1“标准输出”输出文件描述符。

表达式2>&1将文件描述符1复制到位置2,因此在执行环境中写入2的任何输出(“标准错误”)都将转到最初由1描述的相同文件(“标准输出”)。


进一步解释:

文件描述符:“每个进程唯一的非负整数,用于标识用于文件访问的打开文件。”

标准输出/错误:请参阅shell文档的重定向部分中的以下注释:

打开的文件由以零开头的十进制数字表示。最大的可能值是定义的实现;然而,所有实现都应支持至少0到9(包括0到9)供应用程序使用。这些数字称为“文件描述符”。值0、1和2具有特殊含义和常规用途,并由某些重定向操作暗示;它们分别称为标准输入、标准输出和标准误差。程序通常从标准输入中获取输入,并将输出写入标准输出。错误消息通常写在标准错误上。重定向运算符前面可以有一个或多个数字(不允许插入字符),以指定文件描述符编号。

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

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

帮助你记住

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

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

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

你需要从管道的角度来理解这一点。

$ (whoami;ZZZ) 2>&1  | cat
logan
ZZZ: command not found

正如您所看到的,管道LHS的stdout和stderr都被送入(管道的)RHS。

这与

$ (whoami;ZZZ) |& cat
logan
ZZZ: command not found

注意,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管道对此没有兴趣。

文件描述符1是标准输出(stdout)。文件描述符2是标准错误(stderr)。

首先,2>1可能是将stderr重定向到stdout的好方法。然而,它实际上会被解释为“将stderr重定向到名为1的文件”。

&指示后面和前面的是文件描述符,而不是文件名。因此,我们使用2>&1。考虑>&成为重定向合并运营商。