subprocess.Popen 解析命令列表出现问题;管道未正确发送

Posted

技术标签:

【中文标题】subprocess.Popen 解析命令列表出现问题;管道未正确发送【英文标题】:Trouble with subprocess.Popen parsing of the command list; pipe not being sent out correctly 【发布时间】:2013-12-24 09:40:07 【问题描述】:

当我在解释器中运行以下命令时

infile_intersect = subprocess.Popen(['cut', '-f', '1,2,3,4,5', infile, r'|', 'intersectBed', '-a', 'stdin', '-b', bound_motif, '-wo', r'|', 'sort', '-k', '1,1', '-k', '2,2n', '|uniq'], stdout=subprocess.PIPE).communicate()

我收到错误cut: invalid option -- a,但是当我对列表进行空格连接时,它似乎很好

>>> ' '.join(['cut', '-f', '1,2,3,4,5', infile, r'|', 'intersectBed', '-a', 'stdin', '-b', bound_motif, '-wo', r'|', 'sort', '-k', '1,1', '-k', '2,2n', '|uniq'])
'cut -f 1,2,3,4,5 test.bed | intersectBed -a stdin -b ENCODE.tf.bound.union.bed -wo | sort -k 1,1 -k 2,2n |uniq'

似乎管道没有正确发送,但我不确定原因

【问题讨论】:

【参考方案1】:

这不是您使用子流程进行管道传输的方式,使用| 和列表输入表单是无效的。您应该将完整的字符串传递给它并使用shell=True 或像我在下面的示例中所做的那样使用管道:

>>> import subprocess
>>> p = subprocess.Popen(['cat', 'abc1'], stdout=subprocess.PIPE)
>>> p1 = subprocess.Popen(['uniq', '-c'], stdin=p.stdout, stdout=subprocess.PIPE)
>>> print p1.communicate()[0]
      3 word1
      1 word3
      1 word4
      1 word5

使用字符串和shell=True

>>> print subprocess.Popen('cat abc1 | uniq -c', shell=True,
                                            stdout=subprocess.PIPE).communicate()[0]
      3 word1
      1 word3
      1 word4
      1 word5

来自docs:

警告使用shell=True 调用系统外壳可能是一种安全措施 如果与不受信任的输入结合使用会有危险。

【讨论】:

【参考方案2】:

你正在尝试execute a shell pipeline,如果你的输入是可信的,最快的方法是传入shell=True

subprocess.Popen(r'''cut -f 1,2,3,4,5 test.bed | intersectBed -a stdin -b ENCODE.tf.bound.union.bed -wo | sort -k 1,1 -k 2,2n |uniq''', shell=True).communicate()

如果您的输入不可信,您将不得不链接多个 Popen 对象,每个来自管道的命令一个,查看 this SO answer

【讨论】:

以上是关于subprocess.Popen 解析命令列表出现问题;管道未正确发送的主要内容,如果未能解决你的问题,请参考以下文章

subprocess.call和subprocess.Popen

解决subprocess.Popen在windows下执行命令报的KeyError: 'PATH'问题

解决subprocess.Popen在windows下执行命令报的KeyError: 'PATH'问题

如何将字符串解析为 subprocess.Popen 的输入?

从 subprocess.Popen 调用“源”命令

gsutil 的 subprocess.Popen 出现语法错误