2>&1 对 popen 做了什么?

What does 2>&1 do to popen?

2>&1 导致 popen 捕获 stderr

我想了解它是如何工作的。

2、>、&、1 在这里扮演什么角色?
我需要学习什么才能理解它们?

这是一个 shell 结构。这意味着将 (>) stderr(2) 重定向到 stdout(1) 所在的位置。 1stdout 的文件描述符,2stderr 的文件描述符。

$ command 2>&1 #redirect stderr to stdout

$ command 1>&2 #redirect stdout to stderr

$ command 1>output 2>errors #redirect stdout to a file called "output"
                            #redirect stderr to a file called "errors"

popen() 仅捕获 stdout。因此 运行ning 命令使用无法捕获来自其 stderr 的消息。

例如,与

  FILE *fp = popen("command", "r");

只能捕获 command 个中的 stdout 个(使用 fp 读取)。但是有了这个

  FILE *fp = popen("command 2>&1", "r");

stdoutstderr 被捕获。但是通过这种重定向,stdoutstderr 无法区分,因为它们都是混合的。


效果与C中的dup2(1,2);相同。

考虑

#include <stdio.h>
#include <unistd.h>

int main(void)
{
   dup2(1,2);
   fprintf(stdout, "printed to stdout\n");
   fprintf(stderr, "printed to stderr\n");
}

如果这被编译并且 运行 为:

# ./a.out >output

这两行都将打印到名为 output 的文件中。

如果 运行 通过注释掉 dup2() 行的代码。现在只有第一行将被打印到文件中,第二行将被打印在控制台上,即使它仅捕获 stdout 使用重定向 (>).

其他来源:

MSDN 说:

To find File.txt, and then redirect handle 1 (that is, STDOUT) and handle 2 (that is, STDERR) to the Search.txt, type: findfile file.txt>search.txt 2<&1

还有

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

您也可以参考 2.7 Redirection 了解详细信息。

进一步学习的链接:

这是一个基本的文件描述符重定向。它将所有内容从 stderr (2) 重定向到 (>) stdout (&1) 的文件描述符。

一件好事是您还可以同时将标准输出重定向到其他地方。
例如:

command >some-file 2>&1 

有关文件描述符重定向的更多信息(在unix/linux中),我推荐https://www.gnu.org/software/bash/manual/html_node/Redirections.html