2014-12-30 53 views
1

最近我一直在搞Popen。我催生了输出写入TemporaryFile背景的过程:回调函数处理输出

f = tempfile.TemporaryFile() 
p = subprocess.Popen(["gatttool"], stdin = subprocess.PIPE, stdout = f) 

现在它在我通过stdin发送命令到过程和读了一下后临时文件的方式。它是非阻塞的,所以我可以执行其他任务。

问题是,gatttool有时会生成一些输出自身(例如通知)。我正在寻找一种方法来读取此输出,而不会阻止TemporaryFile

我的问题:

1)它是安全的读取从TemporaryFile(50行输出),并希望subprocess优雅地等待我来读取数据或将其终止?

2)是否有一种优雅的方式来创建一个回调函数,该函数将在TemporaryFile上的每个事件上调用(而不是每秒运行一次并读取数据的线程)?

+1

看起来像一个很好的用例命名管道(而不是纯文本文件)。 –

+0

也许:https://docs.python.org/2.2/lib/os-fd-ops.html并使用简单的pipe()? – Melon

+0

个人而言,我喜欢在'sh'模块的子流程中使用更高级别的包装 - 这就是为什么我发布评论而不是编写proprer答案的原因。 –

回答

0

其实分辨率很简单。创建一个pipe,使用gatttool输出作为输入。该管道的输出为thread,它逐行读取该输出并分析每一行。检查它,它的工作原理。请锁定此问题。

# Create a pipe. "gatt_in" ins where the "gatttool" will be dumping it's output. 
# We read that output from the other end of pipe, "gatt_out" 
gatt_out, gatt_in = os.pipe() 

gatt_process = subprocess.Popen(["gatttool", "your parametres"], stdin = subprocess.PIPE, 
           stdout = gatt_in) 

现在每次我想发出一个命令gatttool我这样做:

gatt_process.stdin.write("Some commands\n") 

此命令的结果将在gatt_out apear。在我的情况下,这是在另一个线程处理。

+0

你的意思是'stdout = subprocess.PIPE'? – jfs

+0

你可以发布你用来做这个的代码吗?我是一个Python N00b,我真的很感激看到这个代码。我遇到了同样的问题。 – dgangsta

+0

我会在早上发布代码的第一件事。 – Melon

0

提供输入/得到一个子进程的输出,你可以使用subprocess.PIPE

from subprocess import Popen, PIPE 

p = Popen(['gatttool', 'arg 1', 'arg 2'], stdin=PIPE, stdout=PIPE, bufsize=1) 
# provide input 
p.stdin.write(b'input data') 
p.stdin.close() 
# read output incrementally (in "real-time") 
for line in iter(p.stdout.readline, b''): 
    print line, 
p.stdout.close() 
p.wait() 
+0

使用'''PIPE'''作为stdout将导致应用程序挂起。 '''gatttool'''不发送EOF,它只是坐在那里。另外,在你的例子中,你只提供单行数据,而在我的应用程序中,我提供了一些输入,并将输出汇集到别处 – Melon

+0

@Melon:显然,你可以写多行(调用'p.stdin.write' ),并且不需要在同一个线程中读取:您可以将读取循环放入守护进程线程中,并为每行/每个字节/任何您喜欢的地方调用回调。在内部,'subprocess'模块可以使用'os.pipe()',这样你就不需要自己调用它。 – jfs