创建写入终端

时间:2015-09-21 10:19:13

标签: c++ bash shell

是否可以创建(从shell / Bash或C ++程序中)另外的文件描述符,如STDOUT/STDERR?即默认情况下,它应该将所有输出写入终端并混合两个输出,但如果我想,我可以选择性地重定向它们?

我的用例是以多程序多数据(MPMD)模式运行的MPI并行C ++程序,即几个不相关的功能实体使用不同的数据集同时运行。我想要实现的是,默认情况下,所有输出都被发送到终端,但是我能够将一个或多个输出流重定向到例如一个文件。

2 个答案:

答案 0 :(得分:1)

标准输出和标准错误的文件描述符分别为1和2。启动程序时,子进程默认继承文件描述符。因此,如果在启动程序之前打开文件描述符(例如3),它就可以像使用stdout或stderr这样的另一个特殊FD一样使用它。您可以在bash中打开这样写的FD:

exec 3>/some/file

但请注意,虽然shell通常会将打开的文件描述符传播给它们的子节点,但某些生成其他程序的程序可能会有另一个策略。例如,nohup重定向标准FD但不接触任何其他FD。其他计划虽然不太可能,但可能将所有FD都关闭在2以上。

答案 1 :(得分:0)

您也可以在程序中复制文件描述符,但请注意,这对C ++流不会很好。

要复制一些打开的文件描述符,请调用dup(fd)并返回下一个空闲文件描述符,打开与fd描述符相同的文件。

对于重定向,您可以使用dup2(old, new),这与关闭new相同,然后将其打开到与old相同的文件。

重要的是,当使用上述功能复制或重定向IO时,相应的文件描述符将指向相同的文件描述,这意味着它们共享文件位置和其他一些信息。

我做了一个小demonstrative example,虽然我很难在ideone的限制下让它工作:

#include <unistd.h>
int main(void) {
  // duplicate stdout
  int duplicate = dup(1);
  unsigned counter = 0;
  for (; counter < 10; ++counter) {
    if (counter % 2 == 0) {
      // redirect IO on FD duplicate to stderr
      dup2(2, duplicate);
    } else {
      // redirect it back to stdout
      dup2(1, duplicate);
    }
    write (duplicate, "A ", 2);
    write (1, "B\n", 2);
  }
  close (duplicate);
  return 0;
}

您可以找到有关该here.

的更多信息