简体   繁体   English

Python:subprocess.popen()

[英]Python: subprocess.popen()

I have a question regarding subprocess.popen() : 我有一个关于subprocess.popen()的问题:

If supposedly the command executed is in a while loop - is there any way for subprocess.popen() to detect it and exit after printing the first output? 如果假设执行的命令是在while循环中 - 是否有任何方法让subprocess.popen()检测它并在打印第一个输出后退出?

Or is there any other way to do this and print the result? 或者有没有其他方法来打印结果?

As you see the following program executed on a linux machine just keeps on executing: 如您所见,在Linux机器上执行的以下程序只是继续执行:

  >>> import os
  >>> import subprocess as sp
  >>> p = sp.Popen("yes", stdout=sp.PIPE)
  >>> result = p.communicate()[0]

The communicate method is only useful if the program being called is expected to terminate soon with relatively little output. 只有当被调用的程序预计很快以较少的输出终止时,通信方法才有用。 In the case of your example, the "yes" program never terminates, so communicate never completes. 在您的示例中,“是”程序永远不会终止,因此通信永远不会完成。 In order to deal with subprocesses which execute indefinitely, and may produce a lot of output, you will need to include a loop which repeatedly calls p.poll() until p.poll() returns a value other than None, which would indicate that the process has terminated. 为了处理无限期执行的子进程,并且可能产生大量输出,你需要包含一个重复调用p.poll()的循环,直到p.poll()返回None以外的值,这表示该过程已经终止。 While in this loop you should read from p.stdout and p.stderr to consume any output from the program. 在此循环中,您应该从p.stdout和p.stderr读取以使用程序中的任何输出。 If you don't consume the output, the buffers may fill up and cause the program to block waiting to be able to write more output. 如果不消耗输出,缓冲区可能会填满并导致程序阻塞等待能够写入更多输出。

import subprocess
import time

p = subprocess.Popen("yes", stdout=subprocess.PIPE)
result = ""

start_time = time.time()

while (p.poll() is None):
  result += p.stdout.read(8192)
  time.sleep(1)
  if (time.time() - start_time) > 5:
    print "Timeout"
    break

print result

Note that the above example will run indefinitely until you kill the "yes" subprocess it is reading input from. 请注意,上面的示例将无限期地运行,直到您杀死正在读取输入的“是”子进程。 If you want to detect that the process doesn't terminate, you can add a time check to the while loop, and jump out at some point once enough time has passed. 如果要检测进程是否未终止,可以向while循环添加时间检查,并在经过足够的时间后跳出某个时间点。

If you are certain that your subprocess will terminate of it's own accord, you can simply call communicate() and get back the output, but this does not work in your example for the reasons I explain above. 如果您确定您的子进程将自行终止,您可以简单地调用communic()并返回输出,但由于我在上面解释的原因,这在您的示例中不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM