Empêche la suppression de la tâche Linux en cours d'exécution après la déconnexion de SSH


18

J'ai une tâche de calcul en cours d'exécution pendant quelques jours sur un serveur Linux via une connexion SSH. Ce n'est pas en arrière-plan, donc la connexion SSH est en attente de la tâche.

Je veux redémarrer la machine locale (pas le serveur) à partir de laquelle j'ai ouvert la session ssh, mais je veux que la tâche continue. Est-ce possible?

Réponses:


22

Si votre tâche est déjà lancé, il est trop tard *pour envisager des solutions alternatives insérer une couche supplémentaire entre votre sshsession et le shell en cours d' exécution de la commande, comme screen, tmux, byobu, nohupet les goûts.

Si votre soutien de processus à placer en arrière - plan et ne se bloque pas particulièrement quand stdoutet stderrsont unwritable / fermé, vous pouvez le mettre en arrière - plan avant de vous connecter avec ControlZet bgpuis le détacher de votre coquille avec le disownbuiltin.

par exemple:

$ ssh localhost
You have new mail.
Last login: Fri Jun  6 11:26:56 2014

$ /bin/sleep 3600    


^Z[1] + Stopped                  /bin/sleep 3600
$ bg
[1] /bin/sleep 3600&
$ jobs
[1] +  Running                 /bin/sleep 3600
$ disown %1
$ exit
Connection to localhost closed.
$ ps -ef|grep sleep
jlliagre 12864     1  0 21:12 ?        00:00:00 /bin/sleep 3600
jlliagre 13056 12477  0 21:13 pts/18   00:00:00 grep sleep
$ 

*Comme l'a commenté Bob, il existe en fait plusieurs façons de pirater une session tty sous Linux. vide, retty , injcode et neercs . Le plus avancé semble être reptyr mais vous pourriez avoir besoin des privilèges root pour permettre à ptrace de pirater votre processus.


J'ai utilisé Ctrl + Z, le travail s'est arrêté et est passé en arrière-plan, puis j'ai exécuté la disowncommande. Il a renvoyé: bash: avertissement: suppression du travail 1 arrêté avec le groupe de processus 24876. Mon travail est maintenant répertorié ps -allmais semble ne pas fonctionner (l'utilisation du processeur est de 0%)
Ali

Il semble que mon processus soit arrêté. Je suppose que j'aurais dû fournir une procs ID avec disowncommande
Ali

@Ali Je pense que vous avez oublié d'exécuter la commande bg pour reprendre le travail suspendu.
Jason Zhu

1
@JasonZhu Merci d'avoir signalé cela. Il n'était pas clair que la bgcommande était requise dans la première partie de ma réponse. Édité.
jlliagre

2
Si vous avez oublié la commande bg et que vous n'avez exécuté que la commande disown, vous devriez pouvoir relancer le processus kill -CONTqui fait à peu près la même chose que bg.
kasperd

5

Une solution consiste à utiliser l' écran GNU . Vous pouvez démarrer screen, exécuter votre commande, puis vous détacher C-a d. Plus tard, pour vous reconnecter, faites screen -r, et vous êtes de retour dans votre session précédente.

La gestion des fenêtres présente également d'autres avantages (vous pouvez donc passer à d'autres shells pendant que votre commande est en cours d'exécution, sans avoir besoin d'une nouvelle connexion SSH), et elle permet à votre commande de rester au premier plan, que ce soit dans la session en cours ou plus tard.

Modifier: comme indiqué dans les commentaires, cela ne fonctionnera que si vous vous souvenez de commencer screenavant d'exécuter la commande. Si la commande est déjà en cours d'exécution, vous aurez besoin de la solution de @ jlliagre.


2
tmuxest un autre programme comme screencelui-ci qui vous permet d'avoir une session à distance qui n'est pas liée à votre connexion SSH actuelle.
Dark Android

2
Votre solution est excellente. Cependant, cela ne correspond pas complètement à ma question - j'ai posé une question sur le processus en cours d'exécution, pas sur un processus à exécuter à l'avenir screen.
Ali

Ah ok. Dans ce cas, je pense que vous devrez utiliser la solution de @ jlliagre. (Pour autant que je sache, il n'y a aucun moyen de connecter un processus déjà en cours à quelque chose comme screenou tmux.)
Scott Weldon

1

L'une des façons "standard" de le faire est d'utiliser la nohupcommande incluse dans coreutils, comme ceci:

nohup COMMAND [ARGS] &

Mais la commande redirigera la sortie ( STDOUT& STDERRAFAIK) du programme dans un fichier nohup.out, ce qui le rendra quelquefois ennuyeux parfois (comme générer un énorme fichier journal), donc vous voudrez peut-être faire votre propre redirection, ou la rediriger vers / dev / null si tu veux.


2
Lire à nouveau. Le processus est déjà en cours d'exécution .
Courses de légèreté avec Monica

/ honte n'a pas lu attentivement. Pardon.
wangguoqin1001

nohupPeut en fait être utilisé pour cela. Suspendez simplement le processus en cours et envoyez-le en arrière-plan ( Ctrl+ Zet exécutez bg), puis vous pourrez émettre nohup %1.
Mike

0

En plus de nohupvous pouvez lancer le processus en arrière-plan en utilisant "&" et sous-shell:

Suffixez la commande avec & et enveloppez-la entre parenthèses

$ (thecommand args &)

Disons que votre processus gagne le pid 1922:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11473  2643  0 15:07 pts/1    00:00:00 bash
usr      11922     1  0 15:11 pts/1    00:00:00 thecommand

Regardez qu'il n'est pas attaché au processus shell 11473 qui était son parent d'origine. Donc, si vous quittez ou tuez le shell actuel (11473), le processus 11922 continue de fonctionner et il sera déconnecté des pts.

Essayez de quitter le shell et entrez dans un nouveau shell. Même si ce shell est connecté aux mêmes points, vous pouvez maintenant voir le processus sans point:

$ ps -fp 11922
UID        PID  PPID  C STIME TTY          TIME CMD
usr      11922     1  0 15:11 ?        00:00:00 thecommand

Je ne sais pas comment c'est appelé ou documenté dans Posix, mais j'utilise cette méthode depuis 1990 dans bsh, ksh et maintenant dans bash.

Enfin, vous pouvez utiliser la bgcommande shell intégrée:

Lancez simplement votre programme et si vous décidez de le suspendre ou si vous prévoyez de le garder en arrière-plan, tapez CTRL + Z:

$ thecommand
^Z
[1] Stopped          thecommand

Maintenant, laissez-le continuer à fonctionner en arrière-plan:

$ bg
[1]+ thecommand &

Si vous regardez les infos du processus, il a encore un processus parent:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12046  2643  0 15:18 pts/6    00:00:00 bash
usr      12571 12046  0 16:00 pts/6    00:00:00 thecommand
usr      12601 12046  0 16:04 pts/6    00:00:00 ps -f

Alors, quittez le processus en cours. Le processus en cours d'exécution en arrière-plan est détaché de son parent d'origine et continue de s'exécuter en arrière-plan:

$ exit

Connectez-vous à nouveau et consultez les informations sur le processus:

$ ps -f 12571
UID        PID  PPID  C STIME TTY          TIME CMD
usr      12571     1  0 16:00 ?        00:00:00 thecommand
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.