运行并从后台进程获取输出



我已经知道有几个针对这个主题的问题,但没有一个能解决我的具体问题。或者至少我找不到它。

我需要在后台执行一些程序,等待输出并对其进行操作。但是后台程序必须继续执行

我需要的后台程序中的信息准确地位于其输出的第二行中。如果这个程序阻止我的代码直到到达这一行,没有问题。但它必须在该行之后解锁,这样我才能执行与后台程序完全无关的其他任务。

尽管如此,我仍然无法弄清楚如何做到这一点。我已经阅读了很多subprocess模块的文档,特别是subprocess.Popen.

实用:为什么这段代码不适用于['localtunnel', '8000']参数?它什么也不输出...

我知道我不需要root权限来执行此操作。


在 jadkik94 和 fest 的回答后编辑

不幸的是,这两个答案都对我不起作用。也许我做错了什么...

首先。"健全性检查":

import subprocess, threading, time
can_break = False
def run():
    args = ["ping", "google.com"]
    popen = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE)
    while not can_break:
        print popen.stdout.readline()
t = threading.Thread(target=run)
try:
    t.start()
    while True:
        print 'Main thread...'
        time.sleep(1)
except KeyboardInterrupt:
    can_break = True

上面的代码在类似于以下内容的输出下正常工作:

Main thread...
PING google.com (74.125.234.160) 56(84) bytes of data.
64 bytes from plusone.google.com (74.125.234.160): icmp_req=1 ttl=54 time=82.5 ms
Main thread...
64 bytes from plusone.google.com (74.125.234.160): icmp_req=2 ttl=54 time=82.7 ms
[...]

但是当我将它与我想要的args一起使用时(args = ['localtunnel', 8000](,唯一的输出是 Main thread... .

当我在主线程(阻塞(中调用localtunnel时,它会返回所需的输出:

In [x]: popen = subprocess.Popen(['localtunnel', '8000'])
  This localtunnel service is brought to you by Twilio.
  Port 8000 is now publicly accessible from http://????.localtunnel.com ...

这种方法基于 jadkik94 的答案。但费斯特的回答也行不通。

要以非阻塞方式启动程序,但仍能看到程序的输出,必须在单独的线程或进程中启动程序。Ryan在这里发布了一个很好的代码示例:Python Subprocess.Popen from a thread。

请记住,最后一行print myclass.stdout将打印输出当时的显示方式。如果程序刚刚启动,它可能根本没有输出任何内容,因此您的代码可能应该从myclass.stdout读取,直到收到您需要的行。

您可以在线程中运行它(这样它就不会阻止您的代码运行(,并获取输出,直到您获得第二行,然后等待它终止。这是一个示例,它将读取 Windows 上命令 dir /s 的输出以获取所有目录列表。

import subprocess, thread, time
def run():
    global can_break
    args = ["dir", "/s"]
    shell = True
    count = 0
    popen = subprocess.Popen(args, shell=shell, stdout=subprocess.PIPE)
    while True:
        line = popen.stdout.readline()
        if line == "": continue
        count += 1
        if count == 2:
            do_something_with(line)
            break
    print "We got our line, we are waiting now"
    popen.wait()
    print "Done."
    can_break = True
def do_something_with(line):
    print '>>> This is it:', line
thread.start_new_thread(run, tuple())
can_break = False
while not can_break:
    print 'Wait'
    time.sleep(1)
print 'Okay!'

输出将如下所示:

等>>> 就是这样:卷序列号是XXXX-XXXX我们得到了我们的线,我们现在正在等待等等等...做。等好!

最新更新