在Python中使用subprocess.run()和共享输入替换Bash进程

时间:2018-08-23 12:46:35

标签: python bash

我对使用子进程的python中的bash进程替换有疑问。我正在尝试以一种方式编写它,即主函数和子进程都使用来自stdin的相同输入(在代码中是字符串变量)。这是代码:

p1 = subprocess.run(['cat'],
     stdout=subprocess.PIPE, input=in_fa.encode())
p2 = subprocess.run(['bwa samse reference/C57BL_6J.fa <(bwa aln -l 20 reference/C57BL_6J.fa -) -'],
     shell=True, executable="/bin/bash", input=p1.stdout,
     stdout=subprocess.PIPE)

在此示例中,in_fa是类似于以下的字符串:

 >header\ntTCAGCCTTCCCTTCCATTTCTCTCCCCTTCCCTCTCCTCCCCATTTCAGAGTTTCTTTAGAATCTGTATTCTGGCACCCAAAGTGAACTATGTGTCTGACTCAGGGGCTCTTTGTTTCACTGCAGGGCTGTGGTG

在此代码中,主进程和子进程中的'-'均引用in_fa,但是在主进程正确读取它的同时,子进程却没有。

例如,这可以工作,但是它不是动态的,它是从文件而不是变量中读取的:

p1 = subprocess.run(['''cat fasta/input.fasta |
    bwa samse reference/C57BL_6J.fa <(
        cat fasta/input.fasta |
          bwa aln -l 20 reference/C57BL_6J.fa -) -'],
    shell=True, executable="/bin/bash", stdout=subprocess.PIPE)

任何帮助将不胜感激!同时,我会继续尝试。

1 个答案:

答案 0 :(得分:0)

您不能使用来自两个不同过程的标准输入;他们需要各自收到一份副本。

我的处理方法是将字符串写入临时文件,然后从那里获取。

此外,您的subprocess通话还有两个问题。

  • 您需要传递 字符串或令牌列表。您所看到的似乎可以正常运行,但是定义起来确实不够明确。

  • cat在这里没有任何用处; cat的目的是合并多个文件,而您只有一个文件。 (It wasn't useful in the shell either.

import tempfile
import os

with tempfile.TemporaryDirectory() as tmpdirname:
    fa_tmp = os.path.join([tmpdirname, 'in.fa'])
    with open(fa_tmp, 'wb') as handle:
         handle.write(in_fa.encode())
    proc = subprocess.run(
         '''bwa samse reference/C57BL_6J.fa <(
              bwa aln -l 20 reference/C57BL_6J.fa {0})
              {0}'''.format(fa_tmp),
        shell=True, executable="/bin/bash", 
        check=True, stdout=subprocess.PIPE)

另请参见Running Bash commands in Python,其中有一个答案,概述了您遇到的一些详细问题。