简体   繁体   English

捕获来自Popen的输出

[英]Capturing output from Popen

Maybe what I need is a general explanation of what STDOUT is, but here's my problem. 也许我需要的是对STDOUT的一般解释,但这是我的问题。 I need to run a shell script within python on a bunch of pairs of files, and parse the output. 我需要在一堆文件对上的python中运行shell脚本,然后解析输出。 If I run: 如果我运行:

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'
        ],
    )

... it seems to work great (note: all_ssu is a list of file names essentially). ...看起来效果很好(请注意: all_ssu是文件名列表)。 The shell prints a bunch of lines of data that I'd like to compare. Shell会打印出我想比较的几行数据。 So how do I get that printed data into a list or a dataframe or something so that I can use it? 那么,如何将打印的数据放入列表,数据框或其他内容中以便可以使用呢?

After looking around the docs and some other questions here, it looks like the stdout flag is looking for a file object, so I tried: 在查看了文档和此处的其他一些问题之后,似乎stdout标志正在寻找文件对象,因此我尝试了:

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()

And this also seems to work, except that I create that temporary file that I don't need. 而且这似乎也可行,除了我创建了不需要的临时文件。 I tried just setting a variable captured to None and then putting stdout=captured , but in this case it's just setting captured to 0. I also tried out = Popen(...) without the stdout flag, but again, out is just int(0) . 我尝试了设置变量capturedNone ,然后把stdout=captured ,但在这种情况下,它只是设置captured到0我也试过out = Popen(...)没有stdout的标志,但同样, out只是int(0) I also tried playing around with PIPE , but couldn't make heads or tails of it. 我也尝试过与PIPE玩耍,但无法做到这一点。

So the question is: how do I just capture the output from Popen directly? 所以问题是:如何直接捕获Popen的输出?

From Python 2.7 onwards , you can use - subprocess.check_output 从Python 2.7开始,您可以使用subprocess.check_output

It returns the output of the executed command back as a byte string. 它以字节字符串形式返回执行命令的输出。

Example - 范例-

>>> import subprocess
>>> s = subprocess.check_output(["echo","Hello World!"], shell=True)
>>> s
b'"Hello World!"\r\n'

I had to use shell=True on my windows for this to work, but on linux this may not be needed. 我必须在Windows上使用shell=True才能工作,但是在linux上可能不需要。

Try this: 尝试这个:

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)

from How can I get terminal output in python? 我如何在python中获取终端输出?

STDOUT is just the standard output for the program, which is the file where anything that the program prints will be written to. STDOUT只是程序的标准输出,该文件是程序将打印到的任何内容的文件。

If you want the outputs as a list then you can just create an empty list ( l = [] or something) before the loop and do l.append(out) at the end of each iteration of the loop 如果要将输出作为列表,则可以在循环之前创建一个空列表( l = []或其他内容),并在循环的每次迭代结束时执行l.append(out)

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

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