Windows上的Python子进程输出?

Python subprocess output on windows?(Windows上的Python子进程输出?)
本文介绍了Windows上的Python子进程输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm running into some difficulties getting output from a subprocess stdout pipe. I'm launching some third party code via it, in order to extract log output. Up until a recent update of the third party code, everything worked fine. After the update, python has started blocking indefinitely, and not actually showing any output. I can manually launch the third party app fine and see output.

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

A basic version of the code I'm using:

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("
")
        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)

如果我用 third_party.exe 代替这个脚本,这将完美运行:

This works perfectly if I substitute third_party.exe for this script:

import time, sys

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

所以我不清楚需要做些什么魔法才能让这个与原始命令一起工作.

So I'm unclear as to magic needs to be done to get this working with the original command.

这些都是 subprocess.Popen 行的变体,我尝试过但没有成功:

These are all variants of the subprocess.Popen line I've tried with no success:

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() 的唯一方法是在应用程序启动后不久将其终止,我认为这不会给我有效的结果.

Edit 1: I can't actually use .communicate() in this case. The app I'm launching remains running for long periods of time (days to weeks). The only way I could actually test .communicate() would be to kill the app shortly after it launches, which I don't feel would give me valid results.

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

Even the non-threaded version of this fails:

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("
")
    print "Got: %s" % line

编辑 2:感谢 jdi,以下工作正常:

Edit 2: Thanks to jdi, the following works okay:

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()

推荐答案

首先我建议你简化这个例子,以确保你可以真正阅读任何内容.从混合中删除线程的复杂性:

First I would recommend that you simplify this example to make sure you can actually read anything. Remove the complication of the thread from the mix:

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

如果可行,那就太好了.那么您可能在如何直接或可能在您的线程中读取标准输出时遇到问题.

If that works, great. Then you are having problems possibly with how you are reading the stdout directly or possibly in your thread.

如果这不起作用,您是否尝试过将 stderr 也通过管道传输到 stdout?

If this does not work, have you tried piping stderr to stdout as well?

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

更新

既然你说 communicate() 是死锁的,这里有另一种方法你可以试试看是不是子进程内部缓冲区的问题...

Since you say communicate() is deadlocking, here is another approach you can try to see if its a problem with the internal buffer of subprocess...

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()

这篇关于Windows上的Python子进程输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)