Python - 无法将打开的文件作为stdout传递给Popen

0 投票
2 回答
962 浏览
提问于 2025-04-18 07:14

我现在正在尝试把一个叫做subprocess.Popen的对象的标准输出重定向到一个已经打开的文件里,所以我按照很多网站上的说明去做,比如这个

但是,不知道为什么,Popen.stdout没有正确地被赋值。

我的代码是这样的:

def foo(file):
    print(file)              # printA

    proc = subprocess.Popen('command, stdout=file) # i've tried with both shell=True/False
    print(proc)              # printB
    print(proc.stdout)       # printC
    return proc

def main():
    file = open('path', 'w')
    p = foo(file)
    print(p.stdout)          # printD   

结果如下:

printA: <_io.TextIOWrapper name='path' mode='w' encoding='UTF-8'>
printB: <subprocess.Popen object at 0x161966d0>
printC: None
printD: None

根据我在Python文档中看到的内容,这里提到,如果没有给stdout分配PIPE,默认值是None。但因为这个显示我们可以把一个打开的文件作为stdout的参数传进去,我不明白为什么我的代码不管用。

请帮帮我。

2 个回答

2

你的代码有一些问题,下面是修正后的版本:

def main():
    with open('path', 'w') as f:
        subprocess.Popen(['command'], stdout=f)

你把 file 对象作为参数传给了你的函数,而不是 f 对象。然后在你的函数里,你把全局的 file 对象给覆盖了,虽然碰巧这就是你传给 Popen 的真实 file 对象。

2

我做了一个更简单的例子,结果是这样的:

>>> p = subprocess.Popen('ls', stdout=open('moo','w'))
>>> str(p.stdout)
'None'

不过,文件'moo'确实包含了我当前目录的内容。在用户@eryksun的一个有用提示(见下面的评论)和阅读源代码后,我意识到只有在stdout参数传入PIPE时,p.stdout变量才会被赋值。在其他情况下,它会被设置为None,而这正是上面的例子所展示的。总的来说,一切都按预期工作。

另外,请注意,如果之前的回答是正确的,你在printA中会得到

<type 'file'>

,所以我认为之前的回答是不正确的。

撰写回答