2010-08-18 16 views
25

Me gustaría ejecutar un proceso y no esperar a que vuelva. He tratado de desove con P_NOWAIT y subproceso de esta manera:Ejecutar proceso y no esperar

app = "C:\Windows\Notepad.exe" 
file = "C:\Path\To\File.txt" 

pid = subprocess.Popen([app, file], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE).pid 

Sin embargo, la ventana de la consola permanece hasta que cierro el Bloc de notas. ¿Es posible iniciar el proceso y no esperar a que se complete?

+1

¿Está utilizando 'python.exe' o' pythonw.exe'? –

+5

Aparentemente Python es lo suficientemente inteligente como para darse cuenta de que esas barras invertidas no son caracteres de escape, sin embargo, evitaría hacer eso usando 'r'C: \ path'' o mejor aún' 'C:/path'' –

+0

@NickT o simplemente comillas simples en lugar de dobles – RobotHumans

Respuesta

31

Esta llamada no espera a que finalice el proceso hijo (en Linux). No me preguntes qué hace close_fds; Escribí el código hace algunos años. (Por cierto: La documentación de subprocess.Popen es confuso, en mi humilde opinión.)

proc = Popen([cmd_str], shell=True, 
      stdin=None, stdout=None, stderr=None, close_fds=True) 

Editar:

Miré a la documentación de la subprocess, y creo que el aspecto importante para usted es stdin=None, stdout=None, stderr=None,. De lo contrario, Popen captura la salida del programa, y ​​se espera que lo mires. close_fds hace que los manejadores de archivos del proceso principal sean inaccesibles para el elemento secundario.

+0

Parece que funciona para mí con Python 2.6/2.7 en XP-32b –

+1

¡Oye, Python es realmente portátil! :-) – Eike

+0

Necesito la bandera win32 DETACHED_PROCESS, de lo contrario se cuelga en Windows para mí. – MarcH

18

Finalmente conseguí que esto funcionara. Estoy ejecutando "Python 2.6.6 (r266: 84297, 24 de agosto de 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] win32". He aquí cómo tenía que codificarlo:

from subprocess import Popen 
DETACHED_PROCESS = 0x00000008 
cmd = [ 
     sys.executable, 
     'c:\somepath\someprogram.exe', 
     parm1, 
     parm2, 
     parm3 
     ] 
p = Popen(cmd,shell=False,stdin=None,stdout=None,stderr=None,close_fds=True,creationflags=DETACHED_PROCESS) 

Esto desactiva todas las tuberías de entrada/salida estándar y no ejecuta el programa que se llama en la cáscara. Establecer 'creationflags' en DETACHED_PROCESS pareció ser el truco para mí. Olvidé dónde me enteré, pero se usa un ejemplo here.

+2

la forma correcta de tokenizar es con shlex – RobotHumans

+3

creationflags es solo windows –

0

Creo que la forma más simple de implementar esto es usando la familia de funciones os.spawn* pasando el indicador P_NOWAIT.

Esto, por ejemplo, engendrará un proceso cp para copiar un archivo grande en un nuevo directorio y no molestarse en esperarlo.

import os 
os.spawnlp(os.P_NOWAIT, 'cp', 'cp', '/path/large-file.db', '/path/dest') 
0

Está capturando las entradas y salidas del programa, por lo que su programa no terminará mientras mantenga abiertos esos descriptores de archivos. Si desea capturar, debe cerrar los descriptores de archivo. Si no desea capturar:

app = "C:\Windows\Notepad.exe" 
file = "C:\Path\To\File.txt" 

pid = subprocess.Popen([app, file]).pid 
Cuestiones relacionadas