Bash style process substitution with Python's Popen

后端 未结 1 764
长情又很酷
长情又很酷 2020-12-16 05:40

In Bash you can easily redirect the output of a process to a temporary file descriptor and it is all automagically handled by bash like this:

$ mydaemon --co         


        
相关标签:
1条回答
  • 2020-12-16 06:29

    If pram_axdnull understands "-" convention to mean: "read from stdin" then you could:

    p = Popen(["pram_axdnull", str(kmer), input_filename, "-"],
              stdin=PIPE, stdout=PIPE)
    output = p.communicate(generate_kmers(3))[0]
    

    If the input is generated by external process:

    kmer_proc = Popen(["generate_kmers", str(kmer)], stdout=PIPE)
    p = Popen(["pram_axdnull", str(kmer), input_filename, "-"],
              stdin=kmer_proc.stdout, stdout=PIPE)
    kmer_proc.stdout.close()
    output = p.communicate()[0]
    

    If pram_axdnull doesn't understand "-" convention:

    import os
    import tempfile
    from subprocess import check_output
    
    with tempfile.NamedTemporaryFile() as file:
        file.write(generate_kmers(3))
        file.delete = False
    
    try:
        p = Popen(["pram_axdnull", str(kmer), input_filename, file.name],
                  stdout=PIPE)
        output = p.communicate()[0]
        # or
        # output = check_output(["pram_axdnull", str(kmer), input_filename, 
                                 file.name])
    finally:
        os.remove(file.name)
    

    To generate temporary file using external process:

    from subprocess import check_call
    
    with tempfile.NamedTemporaryFile() as file:
        check_call(["generate_kmers", str(kmer)], stdout=file)
        file.delete = False
    

    To avoid waiting for all kmers to be generated i.e., to write/read kmers simultaneously, you could use os.mkfifo() on Unix (suggested by @cdarke):

    import os
    import shutil
    import tempfile
    from contextlib import contextmanager
    from subprocess import Popen, PIPE
    
    @contextmanager
    def named_pipe():
        dirname = tempfile.mkdtemp()
        try:
            path = os.path.join(dirname, 'named_pipe')
            os.mkfifo(path)
            yield path
        finally:
            shutil.rmtree(dirname)
    
    with named_pipe() as path:
        p = Popen(["pram_axdnull", str(kmer), input_filename, path],
                  stdout=PIPE) # read from path
        with open(path, 'wb') as wpipe:
            kmer_proc = Popen(["generate_kmers", str(kmer)],
                              stdout=wpipe) # write to path
        output = p.communicate()[0]
        kmer_proc.wait()
    
    0 讨论(0)
提交回复
热议问题