Question Garder un processus Linux en cours d'exécution après ma déconnexion


Je me connecte à une machine Linux via SSH et j'essaie d'exécuter un script bash lourd qui effectue des opérations de système de fichiers. On s'attend à ce qu'il continue à fonctionner pendant des heures, mais je ne peux pas laisser la session SSH ouverte en raison de problèmes de connexion Internet que j'ai.

Je doute que l'exécution du script avec l'opérateur d'arrière-plan, l'esperluette (&), fera l'affaire, car je l'ai essayé et plus tard, j'ai trouvé que ce processus n'était pas terminé. Comment puis-je me déconnecter et maintenir le processus en cours?


139
2017-09-15 06:00


origine




Réponses:


La meilleure méthode consiste à démarrer le processus dans un multiplexeur de terminal. Sinon, vous pouvez empêcher le processus de recevoir le signal HUP.


UNE multiplexeur terminal fournit des terminaux "virtuels" qui fonctionnent indépendamment du "vrai" terminal (actuellement, tous les terminaux sont "virtuels" mais c'est un autre sujet pour un autre jour). Le terminal virtuel continuera à fonctionner même si votre terminal réel est fermé avec votre session SSH.

Tous les processus démarrés à partir du terminal virtuel continueront à s'exécuter avec ce terminal virtuel. Lorsque vous vous reconnectez au serveur, vous pouvez vous reconnecter au terminal virtuel et tout se passera comme si rien ne s'était passé, à l'exception du temps écoulé.

Deux multiplexeurs de terminaux populaires sont écran et tmux.

L'écran a une courbe d'apprentissage abrupte. Voici un bon tutoriel avec des diagrammes expliquant le concept: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/


le HUP le signal (ou SIGHUP) est envoyé par le terminal à tous ses processus enfants lorsque le terminal est fermé. L’action commune à la réception de SIGHUP consiste à terminer. Ainsi, lorsque votre session ssh sera déconnectée, tous vos processus se termineront. Pour éviter cela, vous pouvez faire en sorte que vos processus ne reçoivent pas SIGHUP.

Deux méthodes faciles à faire sont nohup et disown.

Pour plus d'informations sur comment nohup et disown travaux lire cette question et réponse: https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

Remarque: bien que les processus continuent à s'exécuter, vous ne pouvez plus interagir avec eux car ils ne sont plus liés à aucun terminal. Cette méthode est principalement utile pour les processus de traitement par lots longs qui, une fois démarrés, n’ont plus besoin de la saisie de l’utilisateur.


132
2017-09-15 06:05



J'aime cette réponse car elle fournit une solution pour les situations interactives et non interactives. Dans le cas interactif, screen vous donne beaucoup plus d'options, mais si vous utilisez authorized_keys pour permettre aux gens d'exécuter un script à distance via ssh, la nohup option est un moyen simple et agréable pour le script de démarrer des processus qui durent plus longtemps que le ssh session utilisé pour les démarrer. - Mark Booth
@rahmanisback - N'oubliez pas que vous pouvez modifier votre réponse acceptée à tout moment. Ce n’est pas parce que jusqu’à présent que la réponse d’EricA est la plus votée, cela ne veut pas dire que c’est la meilleure réponse pour vous. En effet, en faire votre réponse acceptée pourrait bien encourager plus de gens à la voter comme une bonne réponse. - Mark Booth
* toux * tmuxisbetter * toux * - crasic
tmux > écran. Essayez, vous ne reviendrez jamais. - h0tw1r3
@TheLQ - byobu est Écran GNU. Vous utilisez toujours l'écran, avec un fichier .screenrc hautement personnalisé. - EEAA


Il y a plusieurs façons de le faire, mais celle que je trouve la plus utile est d'utiliser Écran GNU.

Après que vous ssh dans, exécutez screen. Cela va démarrer un autre shell en cours d'exécution dans l'écran. Exécutez votre commande, puis faites un Ctrl-une  .

Cela vous "déconnectera" de la session d'écran. À ce stade, vous pouvez vous déconnecter ou faire tout ce que vous souhaitez.

Lorsque vous souhaitez vous reconnecter à la session d'écran, exécutez simplement screen -RD à partir de l'invite du shell (comme le même utilisateur qui a créé la session).


92
2017-09-15 06:07



Impressionnant! Réponse soignée, merci ... - rahmanisback
Screen a tout un tas de commandes, toutes commençant par Ctrl-a. Si vous apprenez seulement un extra, commencez par "Ctrl-a?". Ensuite, vous ne pourrez pas apprendre "Ctrl-a c" et "Ctrl-a n" - olafure
@olafure +1, merci. On dirait que Screen va être ma boîte à outils principale. - rahmanisback
tmux > écran. Essayez, vous ne reviendrez jamais. - h0tw1r3
+1 pour tmux. J'ai abandonné l'écran il y a 5 semaines. - Bryan Hunt


Dans bash, la disown mot-clé est parfaitement adapté à cela. Tout d’abord, exécutez votre processus en arrière-plan (utilisez soit &, ou ^Z puis tapez bg):

$ wget --quiet http://server/some_big_file.zip &
[1] 1156

En tappant jobs vous pouvez voir que le processus est toujours la propriété du shell:

$ jobs
[1]+  Running  wget

Si vous vous déconnectiez à ce stade, la tâche en arrière-plan serait également tuée. Cependant, si vous courez disown, bash détache le travail et lui permet de continuer à s'exécuter:

$ disown

Vous pouvez confirmer ceci:

$ jobs
$ logout

Vous pouvez même combiner les & et disown sur la même ligne, comme:

$ wget --quiet http://server/some_big_file.zip & disown
$ logout

C'est mieux que de courir nohup à mon avis parce que ça ne laisse pas nohup.out les fichiers sont éparpillés sur votre système de fichiers. Également, nohup doit être exécuté avant d'exécuter la commande - disown peut être utilisé si vous ne décidez plus tard que vous voulez détacher la tâche en arrière-plan.


70
2017-09-15 12:27



C'est une très bonne réponse, 1+. La seule préférence pour nohup ou Screen serait l’indépendance de bash et pourrait être utilisée avec d’autres shell. Mais je vais m'en tenir à votre approche chaque fois que j'utilise bash. - rahmanisback
Oui, c'est spécifique à bash, car bash est le seul shell que j'ai jamais utilisé. Je me demande si d’autres coquillages prennent en charge quelque chose de similaire (par exemple, lancer en arrière-plan sans nohup) - il serait fantastique que quelqu'un puisse poster d'autres réponses pour d'autres coquillages. - Jeremy Visser
voir ma réponse montrant comment le faire avec n'importe quel sosie - w00t
+1 pour pouvoir décider plus tard. Juste ce moment, j'avais besoin de ça. travaillé comme annoncé - code_monk


L'outil nohup, disponible sur la plupart des machines Linux, le fera.


37
2017-09-15 06:14



C'est de loin la réponse la plus simple. Toute sortie de est automatiquement dirigée vers nohup.out et peut être examinée ultérieurement. - Julian
nohup ne nécessite pas du tout zsh. - Aaron Brown
nohup est la bonne réponse, c'est court pour ne pas raccrocher. - Kinjal Dixit
nohup se trouve sur beaucoup plus de machines que d’écran, vous devez donc savoir comment vous en servir. - Zenon


Juste pour être minutieux, je signalerai tmux, qui a la même idée de base que l’écran:

tmux se veut une alternative moderne, sous licence BSD, à des programmes tels que GNU Screen. Les principales caractéristiques comprennent:

  • Une interface de commande puissante, cohérente, bien documentée et facilement scriptable.
  • Une fenêtre peut être divisée horizontalement et verticalement en volets.
  • Les volets peuvent être librement déplacés et redimensionnés, ou disposés selon des dispositions prédéfinies.
  • Prise en charge des terminaux UTF-8 et 256 couleurs.
  • Copier et coller avec plusieurs tampons.
  • Menus interactifs pour sélectionner des fenêtres, des sessions ou des clients.
  • Modifiez la fenêtre en cours en recherchant du texte dans la cible.
  • Verrouillage terminal, manuellement ou après un délai d'attente.
  • Une base de code propre, facilement extensible, sous licence BSD, en cours de développement actif.

Cependant, il est environ infiniment plus facile de rechercher sur Google.


27
2017-09-15 06:23



En utilisant "gnu screen" car votre requête de recherche fonctionne assez bien. - gnur
+1000 pour tmux! - mbq


L'écran est excessif pour ne garder que les processus en cours lorsque vous vous déconnectez.

Essayer détacher:

dtach est un programme écrit en C qui émule la fonction de détachement de   écran, qui permet à un programme d'être exécuté dans un environnement qui   est protégé du terminal de contrôle. Par exemple, le programme   sous le contrôle de dtach ne serait pas affecté par le terminal étant   déconnecté pour une raison quelconque.

dtach a été écrit parce que l'écran ne répondait pas correctement à mes besoins; je   n’a pas besoin des fonctionnalités supplémentaires de l’écran, telles que la prise en charge de plusieurs   terminaux ou support d'émulation de terminal. l'écran était aussi trop grand,   encombrant, et avait un code source difficile à comprendre.

l'écran a également interféré avec mon utilisation d'applications plein écran telles que   emacs et ircII, en raison de son interprétation excessive du flux   entre le programme et les terminaux connectés. Dtach n'a pas de   la couche d’émulation terminale et transmet le flux de sortie brut du   programme aux terminaux attachés. Le seul traitement d'entrée qui   dtach effectue effectue une recherche du caractère de détachement (qui signale   détacher du programme) et traiter la touche de suspension   (qui indique à dtach de se suspendre temporairement sans affecter la   programme en cours), et les deux peuvent être désactivés si vous le souhaitez.

Contrairement à screen, dtach a des fonctionnalités minimales et est extrêmement petit.   Cela permet à dtach d'être plus facilement audité pour les bugs et la sécurité   trous, et le rend accessible dans des environnements où l'espace est limité,   comme sur les disques de secours.


11
2017-09-15 15:06



Je vous remercie. Je suis venu ici juste pour poster à propos de Dtach aussi. C'est mon truc de prédilection pour le détachement de terminal maintenant; l'écran fait BEAUCOUP trop, et interfère avec l'entrée à un degré ridicule. L'écran de fait a besoin de sa propre termcap est assez troublant. - fluffy


Voici un moyen de démoniser n'importe quel processus shell, aucun programme externe n'est nécessaire:

( while sleep 5; do date; done ) <&- >output.txt &

Lorsque vous fermez ensuite votre session, le travail continue de s'exécuter comme le prouve le fichier output.txt (qui contient une mise en mémoire tampon, de sorte qu'il faut un certain temps pour afficher une valeur autre que zéro). N'oubliez pas de tuer votre travail après les tests.

Donc, tout ce que vous avez à faire est de fermer stdin et de mettre en arrière-plan le travail. Pour être vraiment bon, d'abord cd / pour ne pas accrocher une monture.

Cela fonctionne même en sh simple sous Solaris.


9
2017-09-16 16:48



Intéressant. Cela a soulevé quelques questions notables. Je peux voir que vous définissez le STDIN à rien, le - opérateur? Quelle est la différence entre < /dev/null et &- ? Je suppose que STDIN (et d’autres STDOUT et STDERR) pourraient se voir attribuer un fichier par < file, ou un flux par <& stream en cas de STDIN. Serait-ce la même chose en utilisant < /dev/null dans votre exemple ci-dessus? Et est-ce que l'opérateur - ci-dessus se réfèrent à une null comme le flux? - rahmanisback
Quand vous faites x <& -, cela ferme le descripteur de fichier x. Dans ce cas, il n’existe pas de x, ce qui fait de bash la valeur 1, c’est-à-dire l’entrée standard. Si vous utilisez </ dev / null, vous ne fermez pas stdin, vous donnez simplement un fichier vide au programme en tant qu'entrée. - w00t
Et pour être honnête, je ne sais pas vraiment pourquoi cela démonise ce que vous utilisez :-) Cela fonctionne bien, nous l'utilisons en production. Je l'ai découvert en m'amusant dans l'espoir de pouvoir démoniser un processus dans un shell sans avoir besoin de quelque chose de spécial - j'ai donc commencé par fermer stdin et cela suffisait. Je devrais aller lire des sources de shell, mais je présume que si vous fermez stdin et mettez en arrière-plan le processus, il le détache également. - w00t
Je pense que la raison en est qu'un SIGHUP (le signal qui provoque la fermeture de l'enfant lorsque le shell meurt) est déclenché lorsqu'un processus parent ferme le descripteur stdin de son enfant. Cependant, si stdin commence en tant que null, plutôt que d'être fermé après le fait, il n'y a aucun moyen pour le parent de déclencher le SIGHUP. Belle trouvaille, cependant, je n'y aurais jamais pensé. - Jeremy Visser
@ JeremyVisser cela semble vraiment plausible! - w00t


le at commande peut être utile pour ce genre de situation. Par exemple, tapez:

at now

Et vous pouvez ensuite entrer une commande ou une série de commandes à exécuter. Les résultats doivent vous être envoyés par courrier électronique, si ce dernier est configuré correctement sur la machine.

Au lieu de now, vous pouvez éventuellement spécifier une heure avec une date ou une expression comme now + 15 minutes. Voir man at pour plus de détails.


7
2017-09-16 08:23





byobu sur Ubuntu est une belle interface à l'écran. En appuyant Ctrl-? vous obtenez une liste de tous les raccourcis clavier. Il ajoute une barre d'état qui peut être utile pour surveiller la charge du processeur, l'espace disque, etc. Globalement, il fournit une expérience que je décrirais comme une connexion VNC basée sur un terminal.

nohup permet de démarrer un travail en arrière-plan avec sa sortie routée vers un fichier journal, qui peut toujours être redirigé vers / dev / null s'il n'est pas requis.


7
2017-09-15 13:26