Exécuter des processus d'arrière-plan en Python et ne PAS attendre
Mon objectif est simple: le coup d'envoi de rsync et de NE PAS ATTENDRE.
Python 2.7.9 sur Debian
Exemple de code:
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"
(J'ai commenté les commandes d'exécution seulement parce que je suis en fait en gardant tous mes essais dans mon code pour que je sache ce que j'ai fait et ce que je n'ai pas fait. Bien évidemment, j'exécutez le script avec la ligne droite sans commentaire.)
Voilà ce qui se passe...je peux regarder le transfert sur le serveur et quand c'est fini, puis je reçois un "FAIT" imprimé à l'écran.
Ce que j'aimerais y arriver, c'est un "FAIT" de l'imprimer immédiatement après l'émission de la rsync
de commande et pour le transfert de commencer.
Semble très simple. J'ai suivi les détails décrits dans d'autres postes, comme cette l'un et cette un, mais quelque chose l'empêche de travailler pour moi.
Merci d'avance.
(J'ai essayé tout ce que je peux trouver dans StackExchange et n'avez pas l'impression que c'est un doublon, car je ne peux toujours pas le faire fonctionner. Quelque chose ne va pas dans ma configuration et ont besoin d'aide.)
pointeur est votre meilleur pari.
celui-ci dit "creationflags" est Windows uniquement. Le lien que vous avez fourni parle Win32, trop.
Avez-vous essayé de simplifier votre code pour voir où est le problème?
subprocess.call("sleep 10".split())
a un retard évident dans le code alors que subprocess.Popen("sleep 10".split())
passe à la ligne suivante immédiatement. Peut-être que votre problème est ailleurs, et difficile à voir? Est-ce que votre code de travail (en termes de timings) si vous avez changé votre rsync appel à un simple sommeil appeler?sans rapport: c'est inutile parler "RIEN de ce qui fonctionne pour moi", à moins de prouver le code exact exemple qui échoue, décrire ce que vous vous y attendiez à faire et ce qui se passe à la place étape par étape.
OriginalL'auteur harperville | 2016-05-05
Vous devez vous connecter pour publier un commentaire.
Ici est vérifiée exemple pour Python REPL:
Comment vérifier que par l'intermédiaire d'une fenêtre de terminal:
De sortie:
Process()
comme recommandé par @asav ci-dessus.J'ai imprimé un message dans le journal après l'appel de Popen que votre exemple montre et j'ai vu mon message dans le journal. Le problème est ailleurs que je n'ai pas encore trouvé mais comme d'habitude, votre suggestion m'a aidé à déterminer Popen n'était pas la question. Merci pour l'aide! Je suis à l'aide de
p = subprocess(rsync_dict, close_fds=True)
est qu'il fonctionne comme annoncé.Je sens que la raison de ce comportement est dans votre commande, ce qui a probablement attend pour une entrée de
stdin
.utilisation stdout=DEVNULL au lieu de la sortie standard stdout=TUYAU sinon, le processus de l'enfant peut se bloquer lorsque le système d'exploitation de la pipe de la mémoire tampon se remplit.
pouvez-vous expliquer pourquoi votre réponse œuvres?
OriginalL'auteur Viach Kakovskyi
Popen()
commence un processus enfant—il ne pas l'attendre à la sortie. Vous devez appeler.wait()
méthode explicitement si vous souhaitez attendre que le processus de l'enfant. En ce sens, tous les sous-processus sont des processus d'arrière-plan.D'autre part, le processus de l'enfant peut hériter de plusieurs propriétés/ressources du parent comme des descripteurs de fichiers ouverts, le groupe de processus, son terminal de contrôle, certains de signal de configuration, etc—, il peut conduire à la prévention des ancêtres processus de sortie par exemple, Python sous-processus .check_call vs .check_output ou l'enfant peut mourir prématurément sur Ctrl-C (SIGINT signal est envoyé à l'avant-plan de groupe de processus) ou si la session de terminal est fermé (SIGHUP).
De dissocier le processus de l'enfant complètement, vous devriez faire un démon. Parfois, quelque chose entre les deux pourrait être assez par exemple, il suffit de rediriger les hérité stdout dans un petit-enfant, de sorte que
.communiquer()
dans le parent serait de retour lorsque son enfant immédiat sorties.naturellement, par exemple
OriginalL'auteur jfs