我已经知道有几个问题针对这个主题,但没有一个问题解决了我的具体问题。或者至少我找不到它。
我需要在后台执行一些程序,等待输出并操作它。 但后台程序必须继续执行。
我需要的后台程序中的信息恰好位于其输出的第二行。如果此程序阻止我的代码直到达到此行,则没有问题。但它必须在该行之后解锁,以便我可以执行与后台程序完全无关的其他任务。
仍然,我无法弄清楚如何实现这一目标。我已经阅读了很多subprocess
模块的文档,特别是subprocess.Popen
。
实际存在:为什么this code不适用于['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
[...]
但是当我将其与{I} 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的答案。但是,费斯特的答案也不起作用。
答案 0 :(得分:1)
要以非阻塞方式启动程序但仍能看到程序输出,程序必须在单独的线程或进程中启动。 Ryan在这里发布了一个很好的代码示例:Python Subprocess.Popen from a thread
请注意,最后一行print myclass.stdout
将打印输出当时显示的输出。如果程序刚刚启动,它可能根本没有任何输出,所以你的代码应该从myclass.stdout
读取,直到它收到你需要的行。
答案 1 :(得分: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!