Wol*_*tan 9 python stdout io-redirection dup2 dup
从python模块我调用一个Hello World可执行文件,只是打印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')
Run Code Online (Sandbox Code Playgroud)
此外,我想恢复重定向之前的stdout.
dup和dup2做什么?/dev/null?sys.stdout = os.fdopen(newstdout, 'w'))StringIO对象中?我很确定,一旦我得到了问题1的答案,问题2和3的答案就很容易了.无论如何我决定发布它们可能会将问题1的答案推到我想去的方向.
jco*_*ado 11
我在下面写了一些额外的注释,这些注释应该更清楚它在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')
Run Code Online (Sandbox Code Playgroud)
需要注意的一件重要事情是,一个进程在启动时从操作系统中获取三个不同的文件描述符:
正如评论中所解释的那样,上面的代码利用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,你将永远看不到你的控制台上生成的文本.
| 归档时间: |
|
| 查看次数: |
3869 次 |
| 最近记录: |