【问题标题】:C restore stdout to terminalC 将标准输出恢复到终端
【发布时间】:2012-06-14 22:27:39
【问题描述】:

我正在使用多线程程序。

首先我将我的标准输出重定向到某个文件。那里没问题(我使用了dup2(fd, 1),其中fd 是文件的文件描述符)。

之后,我需要再次将我的标准输出重定向到终端。

我的第一种方法:

      /*Declaration*/
      fpost_t  stream_sdout;
      /*code*/
      if ( fgetpos( stdout, &stream_sdout) == -1 )
          perror(Error:);

上面写着非法搜索。
不知道为什么会这样。
但如果我让它工作,那么我只需要使用fsetpos(stdout, &stream_stdout) 就可以了。

我的第二个想法是使用dup2(stdout, 4) 将标准输出复制到文件描述符表的位置 4。但这也不起作用。

如何将标准输出切换回其原始目标(终端、管道、文件等)?

【问题讨论】:

  • 我感觉像这样移动stdout 可能是个坏主意——终端 应该在fgetpos() 中准确报告什么位置?为什么不简单地打开一个文件并使用fwrite()fprintf()write() 输出到它,然后在需要时通过/dev/tty 输出到终端?
  • @sarnold:可能是因为程序有库或其他不可更改的代码,它们硬连线到stdout
  • @sarnold 我实际上并没有考虑到这种可能性。让我快速检查一下。
  • 我没有足够的信息来发布一个好的答案,所以我改为发表评论。在 Windows 中,您可以重新连接控制台。我会查看任何 Win32 SDK 文档。这并不难;我只是不记得该怎么做。
  • @sarnold 感谢您的建议!那要容易得多。我能够让它完美地工作。我仍然怀疑是否可以恢复标准,但你的解决方案让我摆脱了困境。谢谢!

标签: c stdout


【解决方案1】:
#include <unistd.h>

...

int saved_stdout;

...

/* Save current stdout for use later */
saved_stdout = dup(1);
dup2(my_temporary_stdout_fd, 1);

... do some work on your new stdout ...

/* Restore stdout */
dup2(saved_stdout, 1);
close(saved_stdout);

【讨论】:

  • 这对我帮助很大。我想知道 close(saved_stdout) 的功能是什么?我用 close 来关闭文件,但我还不熟悉整个 dup 函数过程是如何工作的。
  • @ThinkBonobo, saved_stdout 是程序标准输出下原始文件的原始文件描述符的副本(因此,dup())。当它再次复制回 (dup2()) 标准输出(文件描述符 1 号)时,该程序对于同一个底层文件有两个副本/句柄/描述符。一旦输出重定向完成,就不需要这样做了(它可能会混淆资源限制或关于文件锁定等的假设),所以好的做法是在不再需要时关闭资源。
【解决方案2】:

在执行dup2(fd, STDOUT_FILENO) 之前,您应该通过执行int saved_stdout = dup(STDOUT_FILENO); 将当前打开的文件描述符保存为标准输出(让dup() 为您选择一个可用的文件描述符编号)。然后,在完成将输出重定向到文件后,您可以执行dup2(saved_stdout, STDOUT_FILENO) 将标准输出恢复到开始之前的位置(您也应该关闭saved_stdout)。

您确实需要担心在适当的时候刷新标准 I/O 流 (fflush(stdout)),因为您会搞砸这个。这意味着“在您切换标准输出之前”。

【讨论】:

    【解决方案3】:

    如果程序运行在Linux环境下,可以freopen ("/dev/stdout", "a", stdout)

    但是,如果您知道 stdout 是终端,freopen ("/dev/tty", "a", stdout) 或其他操作系统(甚至是 Windows)的等效项。

    【讨论】:

    • dup2() 工作时,/dev/stdout 应该引用该文件。所以你已经将输出从文件切换到文件,我相信。
    • @JonathanLeffler:如果他正在改变fds,那将是真的。从他的描述来看,这远远不是正在发生的事情。看来他可能正在改变 FILE 连接。
    • 因为他提到使用dup2() 来切换标准输出,在我看来他一开始就搞乱了文件描述符。重置问题的代码很奇怪,无法挽救。重写是为了。当然,这就是答案应该是什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-30
    • 1970-01-01
    相关资源
    最近更新 更多