使用子进程使管道无法在 unix 上工作

Using subprocess to make a pipe not working on unix

我正在尝试创建一个简单的 unix 风格的管道,用于将一个程序的输出链接到另一个程序的输入。我让它在我的 Mac 上工作,但是当我在 linux 服务器 (CentOS) 上尝试它时它失败了,因为外部程序出于某种原因无法理解 -。我不明白这是如何在我的 Mac 而不是 linux 平台上工作的。到目前为止我的代码是:

from subprocess import Popen, PIPE

# Commands to run
p1 = "samtools view -h small.bam".split()
p2 = "samtools view -hb -".split()  # The '-' seems to be the problem
p3 = "samtools view -hb -o fini.bam -".split()

process_list = [p1, p2, p3]


class Pipe_manager(object):
    """Takes a list of commands to run and pipes their in/out together."""
    def __init__(self, process_list):
        self.process_list = process_list
        self.open_processes = []
        self.output = 0
        print 'Starting processes'
        self.__open_procs()

    def __open_procs(self):
        for i in range(len(self.process_list)):
            if i == 0:
                self.open_processes.append(Popen(self.process_list[i], stdout=PIPE))
            else:
                old_pipe = self.open_processes[i-1]
                self.open_processes.append(Popen(self.process_list[i], stdin=old_pipe.stdout, stdout=PIPE))
        self.__close_procs()

    def __close_procs(self):
        for j in range(len(self.open_processes)-1):
            self.open_processes[j].stdout.close()
        self.__get_output()

    def __get_output(self):
        self.output = self.open_processes[-1].communicate()[0]


P = Pipe_manager(process_list)
if P.output:
    print P.output

错误消息是特定于程序的,但可能对这里有帮助:

[main_samview] fail to read the header from "-".

在这种情况下,我该怎么做才能使 unix 工作?

您的 Python 代码看起来很合理。我会检查以确保您的程序确实将 - 理解为 "standard input"。这只是许多程序遵循的约定,但不是任何规范所要求的。

我会在您的 CentOS 机器上的 Bash 会话中手动测试您的管道,看看是否会出现同样的问题。 CentOS(实际上是 RHEL)在更新软件包方面是出了名的 "slow",因此您的 Mac 上可能有更新的版本,它确实理解 -.