【发布时间】:2012-01-11 10:50:21
【问题描述】:
这是来自here 的后续问题。
我想去的地方
我希望能够暂时将标准输出重定向到一个临时文件,而 python 仍然能够打印到标准输出。这将涉及以下步骤:
- 创建标准输出的副本 (
new) - 创建一个临时文件 (
tmp) - 将标准输出重定向到
tmp - 告诉python使用
new作为标准输出 - 将
tmp重定向到“真正的”标准输出中 - 告诉 python 再次使用“真正的”标准输出
- 阅读并关闭
tmp
实施
我尝试通过以下方式实现上述内容:
import os
import subprocess
import sys
#A function that calls an external process to print to stdout as well as
#a python print to pythons stdout.
def Func(s, p = False):
subprocess.call('echo "{0}"'.format(s), shell = True)
if p:
print "print"
sil = list() # <-- Some list to store the content of the temp files
print "0.1" # Some testing of the
Func("0.2") # functionality
new = os.dup(1) # Create a copy of stdout (new)
tmp = os.tmpfile() # Create a temp file (tmp)
os.dup2(tmp.fileno(), 1) # Redirect stdout into tmp
sys.stdout = os.fdopen(new, 'w', 0) # Tell python to use new as stdout
Func("0.3", True) # <--- This should print "0.3" to the temp file and "print" to stdout
os.dup2(new, 1) # Redirect tmp into "real" stdout
sys.stdout = os.fdopen(1, 'w', 0) # Tell python to use "real" stdout again
# Read and close tmp
tmp.flush()
tmp.seek(0, os.SEEK_SET)
sil.append(tmp.read())
tmp.close()
我想在这里休息一下做个总结。
到这里的控制台输出应该是:
0.1
0.2
print
而sil 应如下所示:['0.3\n']。所以直到这里,一切都像魅力一样运作。但是,如果我像这样再次重做上面的脚本:
print "1.1" # Some testing of the
Func("1.2") # functionality
new = os.dup(1) # Create a copy of stdout (new)
tmp = os.tmpfile() # Create a temp file (tmp)
os.dup2(tmp.fileno(), 1) # Redirect stdout into tmp
sys.stdout = os.fdopen(new, 'w', 0) # Tell python to use new as stdout
# This should print "0.3" to the temp file and "print" to stdout and is the crucial point!
Func("1.3", True)
os.dup2(new, 1) # Redirect tmp into "real" stdout
sys.stdout = os.fdopen(1, 'w', 0) # Tell python to use "real" stdout again
# Read and close tmp
tmp.flush()
tmp.seek(0, os.SEEK_SET)
sil.append(tmp.read())
发生错误,输出如下所示:
1.1
1.2
/bin/sh: line 0: echo: write error: Bad file descriptor
print
而sil 读取为:['0.3\n', '']。
换句话说:第二个Func("1.3", True) 无法写入临时文件。
问题
- 首先,我想知道为什么我的脚本不能像我希望的那样工作。意思是,为什么只能在脚本的前半部分写入临时文件?
-
dup和dup2的用法我还是有点疑惑。虽然我认为我了解将 stdout 重定向到临时文件的工作原理,但我现在完全知道为什么os.dup2(new, 1)正在做它正在做的事情。也许答案可以详细说明我脚本中的所有dup和dup2s 正在做什么^^
【问题讨论】:
-
你真的需要做所有这些重复吗?您可以重定向子流程的输出而无需所有这些。
-
@RicardoCárdenes 是的,但从长远来看,我会调用 C 库来愚蠢地打印到标准输出。所以不会涉及任何子流程,这就是我查看
dup的原因。
标签: python stdout io-redirection dup2 dup