windows上的Python子进程输出?

2024-05-23 19:18:25 发布

您现在位置:Python中文网/ 问答频道 /正文

从子进程stdout管道获取输出时遇到了一些困难。我正在通过它启动一些第三方代码,以便提取日志输出。直到最近更新了第三方代码,一切正常。更新之后,python已经开始无限期地阻塞,实际上并没有显示任何输出。我可以手动启动第三方应用程序,然后查看输出。

我正在使用的代码的基本版本:

import subprocess, time
from threading import Thread

def enqueue_output(out):
    print "Hello from enqueue_output"
    for line in iter(out.readline,''):
        line = line.rstrip("\r\n")
        print "Got %s" % line
    out.close()

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1)
thread = Thread(target=enqueue_output, args=(proc.stdout,))
thread.daemon = True
thread.start()

time.sleep(30)

如果我用第三方.exe替换此脚本,则此操作非常有效:

import time, sys

while True:
    print "Test"
    sys.stdout.flush()
    time.sleep(1)

所以我不清楚是否需要使用魔法才能让这个命令和原来的命令一起工作。

这些都是子流程的变体。我尝试过的Popen行没有成功:

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=0)
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, shell=True)
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE)
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, startupinfo=si)

编辑1: 在这种情况下,我不能实际使用.communicate()。我正在发布的应用程序将持续运行很长一段时间(从几天到几周)。我唯一能真正测试.communicate()的方法是在应用程序启动后立即终止它,我觉得这不会给我有效的结果。

即使是非线程版本也会失败:

import subprocess, time
from threading import Thread

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, stderr=subprocess.PIPE)

print "App started, reading output..."
for line in iter(proc.stdout.readline,''):
    line = line.rstrip("\r\n")
    print "Got: %s" % line

编辑2: 多亏了jdi,下面的工作正常:

import tempfile, time, subprocess

w = "test.txt"
f = open("test.txt","a")
p = subprocess.Popen("third_party.exe", shell=True, stdout=f,
                        stderr=subprocess.STDOUT, bufsize=0)

time.sleep(30)

with open("test.txt", 'r') as r:
    for line in r:
        print line
f.close()

Tags: 代码importtrueoutputtimepartystdoutline
2条回答
args = ['svn','log','-v']

def foo(info=''):
    import logging
    import subprocess
    import tempfile
    try:
        pipe = subprocess.Popen(args,bufsize = 0,\
            stdout = subprocess.PIPE,\
            stderr=subprocess.STDOUT)
    except Exception as e:
        logging.error(str(e))
        return False
    while 1:
        s = pipe.stdout.read()
        if s:
            print s,
        if pipe.returncode is None:
            pipe.poll()
        else:
            break
    if not 0 == pipe.returncode:
        return False
    return True

print foo()

这个应该有用,而不是线程,临时文件魔术。

首先,我建议您简化这个示例,以确保您可以实际阅读任何内容。从混合物中去除螺纹的复杂性:

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1)
print proc.communicate()

如果能成功的话,太好了。然后,您可能在如何直接或可能在线程中读取stdout方面遇到问题。

如果这不起作用,你有没有试过用管道把stderr连接到stdout?

proc = subprocess.Popen("third_party.exe", 
                        stdout=subprocess.PIPE, 
                        stderr=subprocess.STDOUT, bufsize=1)

更新

既然您说communicate()是死锁,那么这里有另一种方法,您可以尝试查看它是否是子进程内部缓冲区的问题。。。

import tempfile
import subprocess

w = tempfile.NamedTemporaryFile()
p = subprocess.Popen('third_party.exe', shell=True, stdout=w, 
                        stderr=subprocess.STDOUT, bufsize=0)

with open(w.name, 'r') as r:
    for line in r:
        print line
w.close()

相关问题 更多 >