从python重定向stdout进行C调用
从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')
我也想恢复重定向之前的标准输出。
问题
- 上面的函数到底发生了什么?
- 是什么
dup
和dup2
做什么? - 什么
/dev/null
啊 - 8号线在做什么?(
sys.stdout = os.fdopen(newstdout, 'w')
)
- 是什么
- 如何将标准输出存储在
StringIO
对象中? - 调用 Hello World 程序后如何恢复标准输出?
我很确定,一旦获得问题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')
需要注意的重要一件事是,进程在启动时会从OS获取三个不同的文件描述符:
- 标准输入:0
- 标准输出:1
- 标准错误:2
如评论中所述,上面的代码利用了stdout的文件描述符和文件描述符复制功能来欺骗C代码使用不同的stdout,同时仍保留对python代码中原始stdout的引用。打印。