Python 子进程捕获输出


本文的主要目的是演示如何在 Python 中捕获、存储和显示子进程的输出。


Python 子进程捕获输出

Subprocess 是一个内置的 Python 模块,预装了 Python 安装文件。 它用于通过创建新进程来运行新代码和应用程序,其中给定任务(根据传递的内容)与其进程分开执行。

使用 Subprocess 的主要优点之一是它允许我们从当前编写的程序中启动新程序。

运行此类程序的一个示例是,如果您想从 Git 存储库克隆某个项目,或者可能执行执行其特定任务的 C++ 编译器二进制文件。

假设我们要执行一个用 C++ 编写的程序,其代码如下。

#include <iostream>

using namespace std;

int main()
{
    
    
  int rows = 5, count = 0, count1 = 0, k = 0;
  for(int i = 1; i <= rows; ++i)
  {
    
    
    for(int space = 1; space <= rows-i; ++space)
    {
    
    
      cout << "  ";
      ++count;

    }

  while(k != 2*i-1)
  {
    
    
    if (count <= rows-1)
    {
    
    
      cout << i+k << " ";
      ++count;

    }

    else
    {
    
    
      ++count1;
      cout << i+k-2*count1 << " ";

    }
    ++k;

  }
  count1 = count = k = 0;
  cout << endl;

  }

return 0;
}

哪个打开独立执行给出以下输出:

现在我们执行使用 Python 编写的程序的编译二进制文件。

import subprocess

p2 = subprocess.Popen("program\\pyramid.exe")
print(p2)

输出:

扫描二维码关注公众号,回复: 16192393 查看本文章
<Popen: returncode: None args: '....\\program\\pyramid.exe>
        1
      2 3 2
    3 4 5 4 3
  4 5 6 7 6 5 4
5 6 7 8 9 8 7 6 5

如上面的代码所示,很明显,我们没有获取字符串,而是获取了 Popen 的实例,这不是理想的情况,因为我们需要字符串的输出来对输出或其他内容执行处理 目的。

必须注意的是,我们看到的金字塔输出不是打印名为 p2 的变量的结果,而是使用 Popen 执行的程序的输出。

可以通过多种方式解决此问题,下面将介绍其中的一些方式。


方法 1:使用 check_output 在 Python 中捕获子进程的输出

考虑以下代码:

from subprocess import check_output

out = check_output(["program\\pyramid.exe"])

print(out)

输出:

b'        1 \r\n      2 3 2 \r\n    3 4 5 4 3 \r\n  4 5 6 7 6 5 4 \r\n5 6 7 8 9 8 7 6 5 \r\n'

输出为字节形式,可以使用 decode() 函数轻松将其转换为字符串。

print(out.decode('utf-8'))

输出:

这是我们在名为 out 的字符串变量中所需的输出。

check_output() 函数运行我们想要的命令,并以字节串的形式返回执行程序的命令输出。

然后我们可以使用 decode() 方法将字节字符串转换为普通字符串。 decode() 参数的编码参数可能因输出类型而异。

在我们的例子中,它是 utf-8,但它可能因程序和操作系统而异。


方法 2:使用 Popen.communicate 在 Python 中捕获子进程的输出

考虑以下代码:

import subprocess

pipe = subprocess.Popen("\\program\\pyramid.exe", stdout=subprocess.PIPE)

text = pipe.communicate()[0]

print(text)

输出:

b'        1 \r\n      2 3 2 \r\n    3 4 5 4 3 \r\n  4 5 6 7 6 5 4 \r\n5 6 7 8 9 8 7 6 5 \r\n'

像以前一样,返回一个字节字符串,可以使用 decode() 函数轻松返回。

print(text.decode('utf-8'))

输出:

除了使用 check_output,我们还可以使用 Popen.communicate() 方法,check_output 的主要优点之一是它允许将 stdout 和 stderr 重定向到我们想要的变量。

Popen 返回 stdout 和 stderr 的元组,因此当您访问 [0] 时,您只是在获取 stdout。 你也可以做文本,err = pipe.communicate(),然后文本就会有需要的东西。

就像 check_output 一样,Popen.communicate() 也返回一个字节字符串,在将兼容且合适的编码方案传递给 decode 方法后,可以使用 decode 方法轻松将其转换为普通字符串。

猜你喜欢

转载自blog.csdn.net/fengqianlang/article/details/132136476