这是一个后续问题 这里 特别是关于它的 回答.


从python模块我称 你好世界 可执行的简单打印 Hello World 到stdout。我有兴趣将该输出重定向到Python StringIO 并遇到 这个 回答几乎使我一路走向解决方案。

该答案的关键部分是该代码段:

1. def redirect_stdout():
2.     print "Redirecting stdout"
3.     sys.stdout.flush() # <--- important when redirecting to files
4.     newstdout = os.dup(1)
5.     devnull = os.open('/dev/null', os.O_WRONLY)
6.     os.dup2(devnull, 1)
7.     os.close(devnull)
8.     sys.stdout = os.fdopen(newstdout, 'w')

我也想像重定向之前一样恢复Stdout。

问题

  1. 上面功能到底发生了什么?
    • 什么是 dupdup2 正在做?
    • 什么是 /dev/null?
    • 8行在做什么? ((sys.stdout = os.fdopen(newstdout, 'w'))
  2. 我该如何将Stdout存储在 StringIO 目的?
  3. 打电话给我的电话后,我该如何恢复stdout 你好世界 程序?

我很确定,一旦有了问题1的答案,问题2和3的答案将很容易。我决定将它们发布到任何时候,以将问题1的答案推向我想去的方向。

有帮助吗?

解决方案

我在下面写了一些其他评论,这些评论应该更清楚地表明它正在发生什么 redirect_stdout 功能:

def redirect_stdout():
    print "Redirecting stdout"
    sys.stdout.flush() # <--- important when redirecting to files

    # Duplicate stdout (file descriptor 1)
    # to a different file descriptor number
    newstdout = os.dup(1)

    # /dev/null is used just to discard what is being printed
    devnull = os.open('/dev/null', os.O_WRONLY)

    # Duplicate the file descriptor for /dev/null
    # and overwrite the value for stdout (file descriptor 1)
    os.dup2(devnull, 1)

    # Close devnull after duplication (no longer needed)
    os.close(devnull)

    # Use the original stdout to still be able
    # to print to stdout within python
    sys.stdout = os.fdopen(newstdout, 'w')

要注意的一件重要的事情是,一个过程获得了三个不同的 文件描述符 启动时从操作系统中:

  • stdin:0
  • Stdout:1
  • Stderr:2

如评论中所述,上面的代码利用了stdout的文件描述符和文件描述符重复功能,以使技巧C代码使用不同的stdout,同时仍在对Python代码中的原始stdout进行引用,以便能够打印。

其他提示

/dev/null 是一个特殊的设备文件(Unix中的所有内容都是文件!),它像黑洞一样吞没了所有写入的东西。 dup 复制文件描述符。如果您习惯了Windows,则UNIX中的文件描述符是代表打开文件的特殊整数,就像Windows文件句柄一样。

该程序正在打开 /dev/null 要写(仅),请获取其文件描述符的副本,关闭打开文件(因为拥有文件描述符足以让Unix写入文件,您不需要保持资源的打开),然后分配打开归档到 sys.stdout.

记住 sys 是代表各种系统特定资源(例如文件系统)的Python模块。所以,在Unix中 sys.stdout 将代表 /dev/stdout 即系统 STDOUT 溪流。

因此,总的来说,此代码正在欺骗Python认为 /dev/null/STDOUT 因此,现在每次您的程序写信给 STDOUT 例如, print 语句(python3中的功能),然后确实会写信给 /dev/null 而且,您将永远不会在控制台上看到结果文字。

手动页面 对于C运行时功能,这些功能是这些Python函数的基础。

基本上,他们将文件描述符复制到一个新文件描述符中(带有 dup())或在呼叫中指定的文件描述符中, dup2().

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top