Ejecute el proceso en segundo plano en Python y NO espere

Mi objective es simple: iniciar rsync y NO ESPERAR.

Python 2.7.9 en Debian

Código de muestra:

rsync_cmd = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}@{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1) rsync_cmd2 = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}@{1}:'{2}' {3} &".format(remote_user, remote_server, file1, file1) rsync_path = "/usr/bin/rsync" rsync_args = shlex.split("-a -e 'ssh -i /home/mysuser/.ssh/id_rsa' {0}@{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1)) #subprocess.call(rsync_cmd, shell=True) # This isn't supposed to work but I tried it #subprocess.Popen(rsync_cmd, shell=True) # This is supposed to be the solution but not for me #subprocess.Popen(rsync_cmd2, shell=True) # Adding my own shell "&" to background it, still fails #subprocess.Popen(rsync_cmd, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True) # This doesn't work #subprocess.Popen(shlex.split(rsync_cmd)) # This doesn't work #os.execv(rsync_path, rsync_args) # This doesn't work #os.spawnv(os.P_NOWAIT, rsync_path, rsync_args) # This doesn't work #os.system(rsync_cmd2) # This doesn't work print "DONE" 

(He comentado los comandos de ejecución solo porque en realidad mantengo todas mis pruebas en mi código para que sepa lo que he hecho y lo que no he hecho. Obviamente, ejecutaría el script con el derecho línea sin comentarios.)

Lo que sucede es que … puedo ver la transferencia en el servidor y, una vez finalizada, obtengo un “HECHO” impreso en la pantalla.

Lo que me gustaría que sucediera es un “HECHO” impreso inmediatamente después de emitir el comando rsync y para que comience la transferencia.

Parece muy sencillo. He seguido los detalles descritos en otras publicaciones, como esta y esta , pero algo impide que funcione para mí.

Gracias de antemano.

(He intentado todo lo que puedo encontrar en StackExchange y no creo que esto sea un duplicado porque todavía no puedo hacerlo funcionar. Algo no está bien en mi configuración y necesito ayuda).

Aquí se verifica el ejemplo para Python REPL:

 >>> import subprocess >>> import sys >>> p = subprocess.Popen([sys.executable, '-c', 'import time; time.sleep(100)'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT); print('finished') finished 

Cómo verificar que a través de otra ventana de terminal:

 $ ps aux | grep python 

Salida:

 user 32820 0.0 0.0 2447684 3972 s003 S+ 10:11PM 0:00.01 /Users/user/venv/bin/python -c import time; time.sleep(100) 

Popen() inicia un proceso secundario, no espera a que salga. .wait() llamar al método .wait() explícitamente si desea esperar al proceso hijo. En ese sentido, todos los subprocesos son procesos en segundo plano.

Por otro lado, el proceso hijo puede heredar varias propiedades / recursos del padre, como los descriptores de archivos abiertos, el grupo de procesos, su terminal de control, alguna configuración de la señal, etc., puede llevar a evitar que los procesos de los antepasados ​​salgan, por ejemplo, el subproceso Python. .check_call vs .check_output o el niño puede morir prematuramente en Ctrl-C (la señal SIGINT se envía al grupo de proceso en primer plano) o si la sesión de terminal está cerrada (SIGHUP).

Para desasociar completamente el proceso hijo, debe convertirlo en un demonio . A veces, algo intermedio podría ser suficiente, por ejemplo, es suficiente para redirigir la .communicate() heredada en un nieto, de modo que .communicate() en el padre regrese cuando su hijo inmediato salga .