从python重定向stdout进行C调用

发布于 2021-01-29 17:42:26

从python模块中,我正在调用 Hello World 可执行文件,该文件仅打印Hello World到stdout。我对将输出重定向到pythonStringIO并遇到这个答案很感兴趣,这几乎将我带到了解决方案中。

此答案的关键部分是以下代码段:

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')

我也想恢复重定向之前的标准输出。

问题

  1. 上面的函数到底发生了什么?
    • 是什么dupdup2做什么?
    • 什么/dev/null
    • 8号线在做什么?(sys.stdout = os.fdopen(newstdout, 'w')
  2. 如何将标准输出存储在StringIO对象中?
  3. 调用 Hello World 程序后如何恢复标准输出?

我很确定,一旦获得问题1的答案,问题2和3的答案就会很容易。我决定无论如何都要发布它们,以将问题1的答案推向我想去的方向。

关注者
0
被浏览
151
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我在下面写了一些附加的注释,这些注释应该更清楚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')
    

    需要注意的重要一件事是,进程在启动时会从OS获取三个不同的文件描述符

    • 标准输入:0
    • 标准输出:1
    • 标准错误:2

    如评论中所述,上面的代码利用了stdout的文件描述符和文件描述符复制功能来欺骗C代码使用不同的stdout,同时仍保留对python代码中原始stdout的引用。打印。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看