关于python:捕获Popen的输出

Capturing output from Popen

也许我需要的是对STDOUT是什么的一般解释,但这是我的问题。我需要在python中的一堆文件对上运行shell脚本,并解析输出。如果我跑:

1
2
3
4
5
6
7
8
9
10
11
from itertools import combinations
from subprocess import Popen

for pair in combinations(all_ssu, 2):
    Popen(
        ['blastn',
        '-query', 'tmp/{0}.fna'.format(pair[0]),
        '-subject', 'tmp/{0}.fna'.format(pair[1]),
        '-outfmt', '6 qseqid sseqid pident'
        ],
    )

...它看起来效果很好(注意:all_ssu本质上是文件名列表)。 shell打印了一堆我想要比较的数据行。那么如何将打印数据放入列表或数据框或其他内容以便我可以使用它?

在查看文档和其他一些问题之后,看起来STDOUT标志正在寻找文件对象,所以我尝试了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from itertools import combinations
from subprocess import Popen
for pair in combinations(all_ssu, 2):
    out_file = open('tmp.txt', 'rw')
    Popen(
        ['blastn',
        '-query', 'tmp/{0}.fna'.format(pair[0]),
        '-subject', 'tmp/{0}.fna'.format(pair[1]),
        '-outfmt', '6 qseqid sseqid pident'
        ],
        stdout=out_file
    )
    for line in out_file.readlines():
        print line
    out_file.close()

这似乎也有效,除了我创建了我不需要的临时文件。我尝试将变量captured设置为None然后放入stdout=captured,但在这种情况下,它只是将captured设置为0.我还尝试了out = Popen(...)而没有STDOUT标志,但是再次,< x9>只是int(0)。我也试过玩PIPE,但无法做出正面或反面。

所以问题是:我如何直接从Popen捕获输出?


从Python 2.7开始,您可以使用 - subprocess.check_output

它将执行的命令的输出作为字节串返回。

示例 -

1
2
3
4
5
6
>>> import subprocess
>>> s = subprocess.check_output(["echo","Hello World!"], shell=True)
>>> s
b'"Hello World!"

'

我不得不在我的窗口上使用shell=True来实现这一点,但在Linux上可能不需要这样做。


试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
from itertools import combinations
from subprocess import Popen, PIPE
for pair in combinations(all_ssu, 2):
    out = Popen(
        ['blastn',
        '-query', 'tmp/{0}.fna'.format(pair[0]),
        '-subject', 'tmp/{0}.fna'.format(pair[1]),
        '-outfmt', '6 qseqid sseqid pident'
        ],
        stdout=PIPE
    ).communicate[0]
    print(out)

从如何在python中获得终端输出?

STDOUT只是程序的标准输出,即程序打印的任何内容都将写入的文件。

如果您希望输出作为列表,那么您可以在循环之前创建一个空列表(l = []或其他),并在循环的每次迭代结束时执行l.append(out)