[嗨,我有一个关于将输入和输出与python中的子流程链接的问题。我试图通过将一步的输出传递给另一个子进程而不是将其输出到文件来跳过该步骤,从而简化程序。然后打开另一个进程以对该文件运行。
例如第一个过程使用SAMTOOLS从大型bam文件中输出特定染色体。所以...读取bigfile.bam并输出染色体22.bam
下一个子过程使用BEDTOOLS将那个chromosome22.bam转换为chromosome22.bed所以...染色体22.bam被读入并输出染色体22.bed
我想做的是将第一个进程的标准输出传递给第二个,因此不需要中间文件。
到目前为止,我有这个...
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]
无需在这里使用python。 shell容易得多。但从本质上讲,它的工作原理与python中相同。
如果床具可以从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,强烈建议您学习如何使用python
no shell时,subprocess
更易使用[[安全使用]。进行two子流程调用,每个命令一次。有关更多详细信息,请参见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()
output=$(dmesg | grep hda)
成为:
p1 = Popen(["dmesg"], stdout=PIPE) p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. output = p2.communicate()[0]
说明是:[启动p2之后的p1.stdout.close()
调用很重要,如果p2在p1之前退出,则p1会收到SIGPIPE。
轻微修改:
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)