2012-03-11 58 views
10

我想在下面一行用子:Python子流程:如何使用管道三次?

convert ../loxie-orig.png bmp:- | mkbitmap -f 2 -s 2 -t 0.48 | potrace -t 5 --progress -s -o ../DSC00232.svg 

我发现谢到其他职位the subprocess documentation但我们只使用两次管道的例子。

所以,我尝试了两三个命令和它的作品

p1 = subprocess.Popen(['convert', fileIn, 'bmp:-'], stdout=subprocess.PIPE) 
# p2 = subprocess.Popen(['mkbitmap', '-f', '2', '-s', '2', '-t', '0.48'], stdout=subprocess.PIPE) 
p3 = subprocess.Popen(['potrace', '-t' , '5', '-s' , '-o', fileOut], stdin=p1.stdout,stdout=subprocess.PIPE) 
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p3 exits. 
output = p3.communicate()[0] 

你能帮我的第三个命令?

非常感谢。

+1

你有没有再次尝试与同一过程中的第三命令? – 2012-03-11 14:43:07

+0

为什么你没有尝试过工作?所有在shell中的管道都将一个进程的标准输出连接到另一个进程。 – Dunes 2012-03-11 14:43:56

+0

我不知道在哪里我必须关闭p2以及如何编码输出... – Zorkzyd 2012-03-11 14:47:06

回答

19

只需添加一个第三个命令遵循同样的例子:

p1 = subprocess.Popen(['convert', fileIn, 'bmp:-'], stdout=subprocess.PIPE) 
p2 = subprocess.Popen(['mkbitmap', '-f', '2', '-s', '2', '-t', '0.48'], 
    stdin=p1.stdout, stdout=subprocess.PIPE) 
p1.stdout.close() 
p3 = subprocess.Popen(['potrace', '-t' , '5', '-s' , '-o', fileOut],   
    stdin=p2.stdout,stdout=subprocess.PIPE) 
p2.stdout.close() 

output = p3.communicate()[0] 
+0

我不这么认为,现在他们都联系在一起了,我认为只需要一个“沟通”电话。它有用吗? – 2012-03-11 14:55:15

+0

是的,它现在有效。谢谢:) – Zorkzyd 2012-03-11 15:10:15

+2

'p1.stdout.close()'和'p2.stdout.close()'在'output = p3.communicate()[0]'之后是否有意义? – sandyp 2015-10-09 22:26:23

5

使用subprocess.Popen()的选项shell=True,你可以通过它你的整个命令作为一个字符串。

+0

这往往是要走的路(它肯定会容易得多),但有时你可以遇到文件名引用问题,例如,如果'fileIn'或'fileOut'在名称中有一个空格。可以使用'pipes.quote'来处理大部分时间,但是'shell = False'在技术上更安全。 – torek 2012-03-11 19:32:56

1
def runPipe(cmds): 
try: 
    p1 = subprocess.Popen(cmds[0].split(' '), stdin = None, stdout = subprocess.PIPE, stderr = subprocess.PIPE) 
    prev = p1 
    for cmd in cmds[1:]: 
     p = subprocess.Popen(cmd.split(' '), stdin = prev.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE) 
     prev = p 
    stdout, stderr = p.communicate() 
    p.wait() 
    returncode = p.returncode 
except Exception, e: 
    stderr = str(e) 
    returncode = -1 
if returncode == 0: 
    return (True, stdout.strip().split('\n')) 
else: 
    return (False, stderr) 

然后执行它想:

runPipe(['ls -1','head -n 2', 'head -n 1'])