2012-03-11 7 views
10

Me gustaría utilizar subproceso en la línea siguiente:Subproceso de Python: cómo usar las tuberías tres veces?

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

He encontrado gracias a otros puestos the subprocess documentation pero en el ejemplo utilizamos solamente tubería dos veces.

Por lo tanto, trato de dos de los tres comandos y funciona

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] 

¿me pueden ayudar para el tercer comando?

Muchas gracias.

+1

¿Usted intentó de nuevo para el tercer comando con el mismo proceso? –

+0

¿Por qué no funcionó lo que has intentado? Todo lo que hace la tubería en un shell es la conexión estándar de un proceso para agregar otro. – Dunes

+0

No sé dónde tengo que cerrar la p2 y cómo codificar la salida ... – Zorkzyd

Respuesta

19

Sólo añadir un tercer comando siguiendo el mismo ejemplo:

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

No lo creo, ahora que están todos vinculados, creo que solo se necesita una llamada de 'comunicación'. ¿Funcionó? –

+0

Sí, funciona ahora. Gracias :) – Zorkzyd

+2

¿Importa si 'p1.stdout.close()' y 'p2.stdout.close()' vienen después de 'output = p3.communicate() [0]'? – sandyp

5

Uso subprocess.Popen() con la opción shell=True, y se puede pasar toda su comando como una sola cadena.

+0

A menudo es el camino a seguir (es mucho más fácil) pero a veces puede encontrarse con problemas de cotización de nombre de archivo, por ejemplo, aquí, si 'fileIn' o' fileOut' tenían un espacio en el nombre. Uno puede usar 'pipes.quote' para manejarlos la mayor parte del tiempo, pero dejar' shell = False' es técnicamente más seguro. – torek

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) 

luego ejecutarlo como:

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