comment garder un script python en cours d'exécution lorsque je ferme le mastic

19

Je suis sur le point d'exécuter un script python sur Ubuntu sur VPS. C'est un processus de formation en apprentissage automatique, alors prenez beaucoup de temps pour vous entraîner. Comment puis-je fermer le mastic sans arrêter ce processus.

soupe au poulet
la source
1
Découvrez nohup.
phk

Réponses:

37

Vous avez deux choix principaux:

  1. Exécutez la commande avec nohup. Cela le dissociera de votre session et le laissera continuer à fonctionner après votre déconnexion:

    nohup pythonScript.py

    Notez que la sortie standard de la commande sera ajoutée à un fichier appelé nohup.outsauf si vous le redirigez ( nohup pythonScript.py > outfile).

  2. Utilisez un multiplexeur d'écran comme tmux. Cela vous permettra de vous déconnecter de la machine distante mais, la prochaine fois que vous vous connecterez, si vous exécutez à tmux attachnouveau, vous vous retrouverez exactement dans la même session. La commande sera toujours en cours d'exécution (elle continuera de fonctionner lorsque vous vous déconnecterez) et vous pourrez voir ses stdout et stderr comme si vous ne vous étiez jamais déconnecté:

    tmux 
    pythonScript.py

    Une fois que vous avez lancé cela, fermez simplement la fenêtre PuTTY. Ensuite, reconnectez-vous le lendemain, courez à tmux attachnouveau et vous êtes de retour là où vous avez commencé.

terdon
la source
4
Alternatives à 1 & 2: 1. disown2.screen
heemayl
Il peut également être utile de mentionner byobuun wrapper autour de tmux ou d'un écran.
bli
2

L' screenoutil, disponible pour toutes les distributions Linux, prend en charge cela.

Pour l'installer, exécutez apt-get install screenpour les distributions Linux basées sur deb dnf install -y screenou yum install -y screenpour celles basées sur RPM.

Utiliser:

$ screen

Un nouveau shell est lancé. Dans ce shell, vous pouvez démarrer votre script Python. Ensuite, vous pouvez appuyer sur Ctrl+ Shift+ Apuis D. Il détachera votre terminal du shell qui exécute votre script. De plus, le script est toujours en cours d'exécution.

Pour voir comment fonctionne votre script, vous pouvez appeler screen -r. Cela rattachera votre terminal au shell avec le script Python que vous avez laissé en cours d'exécution en arrière-plan.

UPD: comme Fox l'a mentionné, l'écran fonctionne mal avec systemd, mais nous pouvons utiliser systemd pour démarrer le script, comme on dit dans l'exemple officiel .

Par exemple, si votre script est démarré par /usr/bin/myPythonScript, vous pouvez créer un fichier d'unité Systemd, comme ceci.

$ cat /etc/systemd/system/myPythonScript.service

[Unit]
Description=MyPythonScript

[Service]
ExecStart=/usr/bin/myPythonScript

[Install]
WantedBy=multi-user.target

Ensuite, vous pouvez démarrer ce script # systemctl daemon-reload # systemctl start myPythonScript

Si vous voulez que ce script démarre automatiquement au démarrage du système -

# systemctl enable myPythonScript

À tout moment, vous pouvez voir comment votre script s'exécute

# systemctl status myPythonScript

Annonce que vous pouvez consulter les journaux de votre script

# journalctl -u myPythonScript -e

vodolaz095
la source
Notez que screencela ne fonctionne pas exactement avec systemdsa configuration par défaut. Je ne sais pas si Ubuntu utilise systemd, mais le comportement et la solution de contournement méritent d'être mentionnés dans votre réponse
Fox
1

La plupart des processus peuvent être trompés en redirigeant son stdout, stderr, stdin (tous les descripteurs ne sont pas toujours nécessaires pour rediriger) et en utilisant l' &opérateur de contrôle.

Voir qui ping example.com 1>/dev/null &fait le travail.

Bien sûr, certains programmes sont plus sophistiqués et nécessitent des solutions telles que @terdon mentionné, mais il est bon de savoir et d'utiliser ce qui convient le mieux.

EDIT: comme écrit dans cette réponse tue les systemdprocessus à la déconnexion. Certaines versions des systemdprocessus de suppression à la déconnexion par défaut, d'autres non. Ce comportement peut être modifié en modifiant /etc/systemd/logind.conf en définissant l'option suivante. Tel qu'il est écrit, cela peut également résoudre certains problèmes que vous pourriez rencontrer avec les solutions de @ terdon.

de man logind.conf:

KillUserProcesses=

Prend un argument booléen. Configure si les processus d'un utilisateur doivent être arrêtés lorsque l'utilisateur se déconnecte. Si la valeur est true, l'unité d'étendue correspondant à la session et tous les processus à l'intérieur de cette étendue seront arrêtés. S'il est faux, la portée est "abandonnée", voir systemd.scope (5) et les processus ne sont pas supprimés. Par défaut "oui", mais voir les options KillOnlyUsers=et KillExcludeUsers=ci - dessous.

En plus des processus de session, le processus utilisateur peut s'exécuter sous l'unité de gestion des utilisateurs utilisateur @ .service. Selon les paramètres de persistance, cela peut permettre aux utilisateurs d'exécuter des processus indépendamment de leurs sessions de connexion. Voir la description de enable-lingerin loginctl(1).

Notez que la configuration KillUserProcesses=yescassera des outils comme screen(1) et tmux(1), à moins qu'ils ne soient déplacés hors de la portée de la session. Voir l'exemple en systemd-run(1).

Lisez la réponse liée pour en savoir plus.

mouche en polystyrène
la source
1
Cela envoie simplement le processus en arrière-plan. L'OP souhaite pouvoir se déconnecter d'une session ssh distante et poursuivre le processus. Cela n'aidera pas dans cette situation, la fermeture de la session distante arrêtera la commande même si elle est en arrière-plan.
terdon
@terdon avez-vous vérifié si mon exemple fonctionne? J'ai vérifié et cela fonctionne pour certaines commandes, comme je l'ai écrit dans ma réponse.
mouche en polystyrène voler
Oui, j'ai vérifié et oui, j'ai vu que parfois la commande continue. J'ai cependant très souvent vu que la commande s'arrête donc à moins que vous ne puissiez expliquer exactement quelles commandes continuent ou fournir un moyen de savoir à l'avance si elle continuera ou non, ce n'est pas très utile. En fait, l'exemple spécifique que vous avez donné a échoué lors d'un test que je viens d'exécuter en connectant mon Arch à un système Ubuntu distant.
terdon
@terdon drôle, j'ai vérifié cela sur ArchLinux local se connectant au PLD distant. La seule règle qui fonctionne tout le temps est "le programme utilise-t-il isatty()et se ferme-t-il s'il ne l'est pas?"
mouche en polystyrène voler
Cela pourrait mériter sa propre question. Je sais que j'avais toujours besoin de rien, puis à un moment donné, quelque chose a changé et parfois non. Je ne vois pas comment cela pourrait être l'isatty, si vous quittez le shell parent, cela devrait également tuer l'enfant. Mais oui, parfois non. Je suppose que cela doit être configurable d'une manière ou d'une autre.
terdon