【问题标题】:Duplicate, but still use stdout重复,但仍使用标准输出
【发布时间】:2016-06-01 17:09:25
【问题描述】:

我可以用dup2(或fcntl)做一些魔术吗,以便我将stdout重定向到一个文件(即,写入描述符1的任何内容都会转到一个文件),但是如果我使用了一些其他机制,它会去终端输出?如此松散:

  int original_stdout;
  // some magic to save the original stdout
  int fd;
  open(fd, ...);
  dup2(fd, 1);
  write(1, ...);  // goes to the file open on fd
  write(original_stdout, ...); // still goes to the terminal

【问题讨论】:

    标签: c file unix dup2


    【解决方案1】:

    dup 的简单调用将执行保存。这是一个工作示例:

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    int main()
    {
      // error checking omitted for brevity
      int original_stdout = dup(1);                   // magic
      int fd = open("foo", O_WRONLY | O_CREAT);
      dup2(fd, 1);
      close(fd);                                      // not needed any more
      write(1, "hello foo\n", 10);                    // goes to the file open on fd
      write(original_stdout, "hello terminal\n", 15); // still goes to the terminal
      return 0;
    }
    

    【讨论】:

    • 可能想要使用STDOUT_FILENO 而不是幻数。
    • @EOF 这个想法是尽可能多地保留使用数字常量的原始代码。此外,在 Unix 的上下文中,符号常量等同于拼出数字。对文件描述符的数字引用通常来自 shell 和脚本语言。
    • 使用宏 STDOUT_FILENO 而不是 1 作为描述符编号将使代码更具可读性;我认为可读性非常重要。关于脚本语言,我不同意:例如awksed 没有任何文件描述符的概念。 gawk 和 mawk 支持特殊名称 /dev/stdin/dev/stdout/dev/stderr(即使在 Windows 中)。那些了解文件描述符的脚本语言从 C 中继承了概念(主要是接口),并且也确实具有命名常量(例如 Perl、Python)。
    • @NominalAnimal 可读性很重要,教育也很重要,尤其是在 SO 答案空间有限的情况下。提供的 sn-p 显示代码运行 unchanged 只是添加了dup。随着时间的推移,OP 会从这些 cmets 中了解符号常量。
    • @user4815162342 感谢您的出色回答。没想到这么简单。我以为dup2 会关闭标准输出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2018-01-09
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多