链接Python中的子进程

时间:2012-01-30 18:11:08

标签: python subprocess

您好我有一个关于将输入和输出与python中的子进程相关联的问题。我试图通过将其传递给另一个子进程而不是将其输出到文件来跳过一步的输出来简化程序。然后打开另一个进程以在该文件上运行。

E.g。第一个过程使用SAMTOOLS从大型bam文件输出特定染色体。 所以... 读入bigfile.bam并输出chromosome22.bam

下一个子进程使用BEDTOOLS将该染色体22.bam转换为染色体22.bed 所以... 读入染色体22.bam并输出染色体22.bed

我想要做的是将第一个进程的stdout传递给第二个进程,这样就不需要中间文件了。

到目前为止,我有这个......

for x in 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,'X','Y':
   subprocess.call("%s view -bh %s %s > %s/%s/%s.bam" % (samtools,bam,x,bampath,out,x), shell=True)

这使得染色体[1-22,X,Y] .bam文件。但是我可以避免这种情况并在同一个循环中放入另一个子进程命令将它们转换为床文件吗?

床转换命令是:

bedpath/bedtools bamtobed -i [bamfile] > [bedfile]

3 个答案:

答案 0 :(得分:4)

请查看文档中的replacing shell pipeline示例。

答案 1 :(得分:1)

这里不需要使用python。在 shell 中容易得多。但实质上,它与python中的工作方式相同。

如果bedtools可以从stdin读取,你可以例如做

#!/bin/sh
for x in `seq 1 22` X Y; do
   $samtools view -bh $bam $x | $bedtools bamtobed > $bampath/$out/$x.bam
done

根据bedtools的设置方式,您可能还需要使用-i -将其从stdin读取。

如果你坚持使用python,我强烈建议你学习如何做到这一点

  1. 没有在所有shell中执行,
  2. 不生成shell命令,需要正确转义以避免错误
  3. 当您使用基于数组的语法和 no shell 时,

    subprocess可以更安全地使用。 进行两个子进程调用,每个命令一个。有关详细信息,请参阅http://docs.python.org/library/subprocess.html#replacing-shell-pipeline

    cmd1 = [samtools, "view", "-bh", bam, x]
    cmd2 = [bedtools, "bamtobed"]
    
    c1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)
    c2 = subprocess.Popen(cmd2, stdin=c1.stdout, stdout=open(outputfilename, "w"))
    c1.stdout.close()
    c2.communicate()
    

答案 2 :(得分:0)

是的,您可以使用管道功能。看看你是否可以从stdin中读取bamtobed进程...如果可以,请尝试以下方法。这样,假设处理负载较轻,您可以节省磁盘IO时间。

轻微修改:

proc1.stdout现在是第二个进程的标准输入。

proc1 = subprocess.call("%s view -bh %s %s" % (samtools,bam,x,bampath,out,x), shell=True, stdout=subprocess.PIPE)

proc2 = subprocess.call("bedpath/bedtools bamtobed > %s" % (outFileName, ), shell=True, stdin=proc1.stdout)