Python子进程有两个输入

时间:2012-06-21 16:00:35

标签: python subprocess

我正在编写一个需要调用外部程序hmm3align的Python程序,该程序从命令行运行如下:

hmm3align hmm_file fasta_file -o output_file

通常,程序需要两个输入文件并将结果写入第三个文件。我的程序实际上有多个调用外部程序的情况,但这是外部程序有两个文件输入的唯一情况。我的目的是避免编写和读取文件以允许这些外部程序相互通信;我希望在会话期间将所有数据存储为Python变量,并在需要时将这些变量提供给外部程序。

在需要调用hmm3align的Python程序中,我已经有两个Python变量hmm_model和fasta_model,它们分别包含通常包含在hmm_file和fasta_file中的信息。我想做的是通过stmm传递hmm_model和fasta_model来调用hmm3align(因为我认为这是将它们作为输入提供的唯一方法),然后将stdout中的结果捕获到名为align_results的第三个Python变量中。为此,我创建了一个单独的函数,它使用子进程模块,如下所示:

def hmmalign(hmm_model,fasta):
     args = ["/clusterfs/oha/software/bin/hmm3align",
             "-", "-",
             "-o", "/dev/stdout"]
     process = subprocess.Popen(args, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     return process.communicate(hmm_model,fasta)[0]

所以你可以看到,我试图通过stdin发送两个变量。 args列表中的两个“ - ”用于捕获这两个变量;我看过其他例子中使用的“ - ”,但其目的不明确,我可能误解了事情。

果然,我在Traceback结束时收到以下错误:

TypeError: communicate() takes at most 2 arguments (3 given)

所以我不能通过stdin将两个单独的变量传递给程序。我应该提一下,当该程序只需要一个输入文件时,我已经能够在类似的外部程序上运行子进程。

如何使这项工作?是否可以使用具有多个输入的子进程?我查看了文档并没有看到这个问题的答案。提前谢谢。

1 个答案:

答案 0 :(得分:1)

标准输入是单个数据流;在Unix上,它是连接到单向管道输出端的文件描述符。按照惯例,从命令行上指定的单个文件读取的程序将-理解为从stdin而不是从文件读取的指令。但是,对于从两个文件读取的程序,无法从stdin读取两次,因为它是单个数据流。

还有其他文件描述符可用于通信(stdin是fd 0,stdout是fd 1,stderr是fd 2)但是没有传统的方法来指定它们而不是文件。

最有可能在这里工作的解决方案是 named pipes (FIFO);在Python中,使用os.mkfifo创建命名管道,使用os.unlink删除它。然后,您可以在写入程序时将其名称传递给程序(它将显示为可以读取的文件)(使用open)。