2012-05-15 53 views
2

我已经知道有几个问题针对这个主题,但是他们都没有解决我的具体问题。或者至少我找不到它。运行并从后台进程获得输出

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

来自我需要的后台程序的信息恰好位于其输出的第二行。如果此程序阻止我的代码直到到达此行,则不会有任何问题。但重要的是它在该行之后解锁,以便我可以执行与后台程序完全无关的其他任务。

不过,我不知道如何做到这一点。我已经阅读了很多subprocess模块的文档,特别是subprocess.Popen

作为实践:为什么this code不适用于['localtunnel', '8000']论点?它不输出任何...

我知道我不需要root权限来执行此操作。从jadkik94答案后


编辑和巨星

遗憾的是,答案并不为我工作。也许我做错了什么...

首先。 A“健全检查”:

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...

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 

上面的代码类似于此输出工作正常。

当我在主线程(阻塞)调用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的答案。但是,费斯特的答案也不起作用。

+0

需要明确的是:在Python脚本是否需要任何后台程序的输出超过第二行?还是只需要让它继续运行? –

+0

第二行后,后台程序可以“隐藏”其输出。 – borges

回答

1

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

请记住,它如何出现当时最后一行print myclass.stdout将打印输出。如果程序刚启动,它可能根本没有输出,所以你的代码应该从myclass.stdout中读取,直到它接收到你需要的行。

+0

请参阅我上面的编辑。 – borges

1

你可以在一个线程中运行它(这样它不会阻止你的代码运行),并获得输出,直到获得第二行,然后等待它终止。这是一个例子,它将读取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!' 

输出如下:

 
Wait 
>>> This is it: Volume Serial Number is XXXX-XXXX 

We got our line, we are waiting now 
Wait 
Wait 
Wait 
. 
. 
. 
Done. 
Wait 
Okay! 
+0

请看看我上面的编辑。 – borges

+0

看来你对1)它在一个线程中运行的事实(我们有问题)2)你传递给'subprocess.Popen'的参数有问题。所以试着在一个线程中运行它,就像你在主函数中运行一样:'subprocess.Popen(args)' – jadkik94

+0

还有一件事情:带有新行或不带有参数的args输出是“Main Thread ...”?应该有大量的新行,因为'popen.stdout.readline()'应该返回一些东西......并且你正在打印它。我会试着让'localtunnel'在这里运行,然后自己看看。 – jadkik94

相关问题