简体   繁体   English

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

[英]Bash process substitution in Python with subprocess.run() and shared input

I have a question regarding bash process substitution in python using subprocess. 我有一个关于使用子进程在python中进行bash进程替换的问题。 I'm trying to write it in a way that both the main function and the subprocess use the same input from stdin (which in the code is a string variable). 我正在尝试以一种方式编写它,即主函数和子进程都使用来自stdin的相同输入(在代码中是字符串变量)。 Here is the code: 这是代码:

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 this example, in_fa is a string like the following: 在此示例中, in_fa是类似于以下的字符串:

 >header\ntTCAGCCTTCCCTTCCATTTCTCTCCCCTTCCCTCTCCTCCCCATTTCAGAGTTTCTTTAGAATCTGTATTCTGGCACCCAAAGTGAACTATGTGTCTGACTCAGGGGCTCTTTGTTTCACTGCAGGGCTGTGGTG

In this code, both '-' in the main process and the subprocess refer to in_fa , but while the main process is reading it correctly, the subprocess is not. 在此代码中,主进程和子进程中的“-”都引用in_fa ,但是当主进程正确读取它时,子进程却没有。

This, for example, would work, but it's not dynamic and it's reading from a file instead than a variable: 例如,这可以工作,但它不是动态的,它是从文件而不是变量中读取的:

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)

Any help would be appreciated! 任何帮助,将不胜感激! Meanwhile, I will keep trying. 同时,我会继续尝试。

You cannot consume standard input from two distinct processes; 您不能使用来自两个不同过程的标准输入; they need to receive a copy each. 他们需要各自收到一份副本。

My approach to this would be to write the string to a temporary file and take it from there. 我的解决方法是将字符串写入临时文件,然后从那里获取。

In addition, your subprocess calls have a couple of problems. 此外,您的subprocess调用还有两个问题。

  • You need to pass in either a string or a list of tokens. 你需要在一个字符串标记列表通过。 What you have looks like it's working, but it's really not well-defined. 您所看到的似乎正在运行,但实际上定义不明确。

  • The cat performs no useful purpose here; cat在这里没有任何用处。 the purpose of cat is to combine multiple files, and you only have one file. cat的目的是合并多个文件,而您只有一个文件。 ( It wasn't useful in the shell either. ) 它在shell中也没有用。

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)

See also Running Bash commands in Python where I have an answer which outlines some of the problems you are having in more detail. 另请参见在Python运行Bash命令,在这里我有一个答案,概述了您遇到的一些更详细的问题。

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

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