Python:subprocess.popen()

发布于 2024-10-30 05:20:34 字数 367 浏览 0 评论 0原文

我有一个关于 subprocess.popen() 的问题:

如果据说执行的命令是在 while 循环中 - 有没有办法让 subprocess.popen() 检测到它并打印第一个输出后退出?

或者还有其他方法可以做到这一点并打印结果吗?

正如您所看到的,在 Linux 机器上执行的以下程序继续执行:

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

I have a question regarding 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?

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:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

享受孤独 2024-11-06 05:20:34

仅当被调用的程序预期很快终止且输出相对较少时,communicate 方法才有用。在您的示例中,“yes”程序永远不会终止,因此通信永远不会完成。为了处理无限执行并可能产生大量输出的子进程,您需要包含一个循环,该循环重复调用 p.poll() 直到 p.poll() 返回 None 以外的值,这表明该过程已终止。在此循环中,您应该读取 p.stdout 和 p.stderr 以使用程序的任何输出。如果您不消耗输出,缓冲区可能会填满并导致程序阻塞等待能够写入更多输出。

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

请注意,上面的示例将无限期地运行,直到您终止它正在读取输入的“yes”子进程。如果你想检测进程没有终止,你可以在 while 循环中添加一个时间检查,并在经过足够的时间后在某个时刻跳出。

如果您确定您的子进程将自行终止,您可以简单地调用communicate()并获取输出,但由于我上面解释的原因,这在您的示例中不起作用。

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. While in this loop you should read from p.stdout and p.stderr to consume any output from the program. 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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文