将标准输出从子进程流到python函数,然后返回到子进程

2024-06-17 10:45:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在unix风格的管道中使用python。 例如,在unix中,我可以使用管道,例如:

$ samtools view -h somefile.bam | python modifyStdout.py | samtools view -bh - > processed.bam

我可以通过在python脚本中使用一个for line in sys.stdin:循环来实现这一点,它似乎可以正常工作。在

不过,我希望将这个unix命令内部化为python脚本。所以基本上我会避免进程间的大文件阻塞行为。在

目前,我试图使用Popen来管理每个命令,并将第一个进程的stdout传递给下一个进程的stdin,依此类推。在

在一个单独的python脚本中我有(sep_进程.py)公司名称:

^{pr2}$

在我的python主脚本中,我有以下内容:

import sys
from subprocess import Popen, PIPE

# Generate an example file to use
f = open('sees.txt', 'w')
f.write('somewhere over the\nrainbow')
f.close()

if __name__ == "__main__":
    # Use grep as an example command
    p1 = Popen("grep over sees.txt".split(), stdout=PIPE)

    # Send to sep_process.py 
    p2 = Popen("python ~/Documents/Pythonstuff/Bam_count_tags/sep_process.py".split(), stdin=p1.stdout, stdout=PIPE)   

    # Send to final command
    p3 = Popen("wc", stdin=p2.stdout, stdout=PIPE)

    # Read output from wc
    result = p3.stdout.read()
    print result

但是p2进程失败[Errno 2] No such file or directory,即使文件存在。在

我需要实现某种类型的Queue和/或使用多处理模块打开python函数吗?在


Tags: topy脚本view管道进程stdinstdout
2条回答

谢谢@cdarke,这解决了使用grep、wc等简单命令的问题,但是我太蠢了子流程.Popen在使用samtools等可执行文件提供数据流时工作。在

为了解决这个问题,我创建了一个包含管道的字符串,就像我在命令行中写的一样,例如:

sam = '/Users/me/Documents/Tools/samtools-1.2/samtools'
home = os.environ['HOME']    
inpath = "{}/Documents/Pythonstuff/Bam_count_tags".format(home)

stream_in = "{s} view -h {ip}/test.bam".format(s=sam, ip=inpath)
pyscript = "python {ip}/bam_tags.py".format(ip=inpath)
stream_out = "{s} view -bh - > {ip}/small.bam".format(s=sam, ip=inpath)

# Absolute paths, witten as a pipe
fullPipe = "{inS} | {py} | {outS}".format(inS=stream_in, 
                                              py=pyscript,
                                              outS=stream_out)

print fullPipe
# Translates to >>>
# samtools view -h test.bam | python ./bam_tags.py | samtools view -bh - > small.bam 

然后,我使用了os模块中的popen,这与预期一样工作:

^{pr2}$

波浪号~是一个shell扩展。您没有使用shell,因此它正在查找名为~的目录。在

您可以读取环境变量HOME并插入该变量。使用

os.environ['HOME']

或者,如果您不介意自己进行扩展,可以使用shell=True。在

相关问题 更多 >