Reprendre la commande en cours d'exécution dans une session SSH abandonnée

32

La lecture de cette question m'a fait me demander. En supposant qu'il screenn'est pas utilisé. Si une session SSH sur une cible Linux est abandonnée, pour une raison quelconque, et que vous vous reconnectez avant que le serveur ne tue la session en raison du délai d'expiration, est-il possible de reprendre le contrôle de la commande en cours d'exécution de sorte qu'elle ne soit pas abandonnée en raison de la session interrompue ?

John Gardeniers
la source
De quelle commande s'agit-il? Je suppose que la réponse est généralement non.
davr
Aucune commande particulière, je demande simplement comme concept général.
John Gardeniers
1
Quelqu'un qui comprend parfaitement comment les sessions tty sont initialisées pourrait être en mesure de nous dire comment. Il semble que si vous pouviez recréer une nouvelle session sur le même tty et affecter explicitement le PPID précédent, cela pourrait être possible. J'attends juste qu'un gourou du nix barbu vienne nous souffler. C'est le rêve de toute façon.
CarpeNoctem
Que se passe-t-il si vous expérimentez avec un ordinateur portable connecté et que vous retirez le cordon Ethernet?
Paul
@ ~ drpaulbrewer - Exactement la même chose que lorsque vous faites cela avec une machine de bureau - la connexion est interrompue. La façon dont la connexion est interrompue n'a aucun rapport avec la question.
John Gardeniers

Réponses:

13

Tenter de connecter les descripteurs de fichier STD * actuels d'un nouveau terminal à un ancien processus en cours d'exécution pose simplement des problèmes. Même si vous parvenez à le faire, le contrôle des tâches du terminal ne fonctionnera pas comme prévu. Vous aurez un gâchis si vous quittez finalement le programme repris, et ce qui arrive au shell qui a sacrifié ses descripteurs de fichiers pour être remis au processus nouvellement mis en arrière-plan. Ssh restera-t-il ouvert lorsque ce shell disparaîtra? Probablement pas. Vous devrez donc d'abord le rediriger ailleurs.

Possible ou non, je parierais qu'il est plus souhaitable de laisser le processus abandonné être tué "naturellement". Si vous faites quelque chose d'assez important pour justifier d'essayer de faire tout le piratage nécessaire pour reprendre le contrôle et que vous êtes sur un lien instable, vous devriez probablement le savoir à l'avance et utiliser simplement screen (ou vnc, ou tout ce qui flotte votre détaché) bateau de contrôle). :)

dannysauer
la source
J'ai du mal à choisir une réponse à accepter, donc j'accepte celle-ci parce qu'en ce moment, c'est la seule qui a un vote positif.
John Gardeniers
5

Je sais que c'est une vieille question, mais je pensais qu'il était important d'ajouter mes conclusions au cas où quelqu'un d'autre trouverait cela comme moi.

Je n'ai pas vu de conséquences inhabituelles à faire cela oui, mais c'est ce que j'ai utilisé et cela a fonctionné de manière incroyable. Parfois, lorsque nous exécutons de longs processus sur notre serveur, cela déconnecte parfois la session ssh. Le processus avec la session tty semble continuer mais nous ne pouvons pas nous reconnecter. J'ai trouvé le programme ci-dessous pour tirer le processus vers la session nouvellement connectée.

https://github.com/nelhage/reptyr

Voici plus d'informations

https://blog.nelhage.com/2011/02/changing-ctty/

user215086
la source
5
Bienvenue dans Server Fault! Bien que cela puisse théoriquement répondre à la question, il serait préférable d’inclure ici les parties essentielles de la réponse et de fournir le lien à titre de référence.
EEAA
merci @ user215086! Étonnamment, cela a fonctionné! J'étais en train de modifier un long fichier de configuration pendant un certain temps, j'ai ajouté un tas de paramètres personnalisés et des commentaires soigneusement écrits, et j'étais presque terminé lorsque la connexion a chuté! "Noooooo !! ..." Après avoir fini de crier des blasphèmes au plafond, j'ai installé reptyr, et le tour est joué! J'ai récupéré la session ssh juste là où je l'ai laissée dans l'éditeur, j'ai terminé quelques choses, sauvé, fait !! WooHoo! reptyr est génial.
ColdCold
4

Généralement, la bonne façon de gérer cela est de s'y préparer à l'avance, en utilisant GNU screenou bash nohupou des disownmécanismes. Si vous utilisez tcsh, le shell désactive les tâches d'arrière-plan lorsqu'il se ferme anormalement.

Si vous n'utilisez pas screenmais avez réussi à maintenir votre processus en cours d'exécution via l'une des méthodes refusées , vous pourriez être en mesure de simuler la reconnexion au processus avec gdb( source ):

[...] avec quelques hacks sales, il n'est pas impossible de rouvrir un processus stdout / stderr / stdin. [...]

Et puis utilisez gdb par exemple pour vous attacher au processus, faites un appel close (0)
call close (1)
call close (2)
call open ("/ dev / pts / xx", ...)
call dup (0)
appeler dup (0)
detach

Maintenant, vous devez modifier ce processus pour votre situation. Je doute que cela aiderait si vous n'avez pas réussi à renier le processus. Si vous utilisez bash, voir ce billet de faire bash automatiquement désavouer les processus d'arrière - plan sur la sortie (essentiellement, éteignez huponexit avec shopt ). Avec un processus de premier plan, vous devez avoir utilisé nohup .

Quack Quack
la source
1

Probablement pas. Je ne peux pas garantir que c'est impossible mais j'en doute vraiment.

Une chose est le manque de tuer le shell et les commandes possibles s'exécutant à la suite de la fin de la connexion ssh. Ce n'est pas si difficile, vous devriez pouvoir utiliser nohup et des mécanismes similaires comme mentionné dans l'autre question.

Mais alors, supposez que vous avez commencé ssh somehost nuhup vim /some/fileet que la connexion s'éteint. Vous exécutez ssh somehostpour vous connecter à nouveau et pouvez voir que votre processus vim est toujours en cours d'exécution. Mais alors, comment vous connectez-vous à nouveau à ce processus? Les processus interactifs forground ont un tty de contrôle et celui ouvert pour votre processus vim au démarrage aurait depuis été fermé. Je ne sais pas s'il existe un moyen de le "rouvrir" à nouveau dans votre nouveau shell (tout comme si vous avez plusieurs tâches d'arrière-plan en cours d'exécution dans un shell, vous ne pouvez pas mettre en avant celles de l'autre shell).

Screenont été explicitement écrits pour avoir cette fonctionnalité. Au démarrage, il bifurque deux processus, un processus de gestion de terminal et un processus client. L'interaction est l'application <--> gestionnaire de terminaux <--> client, et lorsque vous vous déconnectez ou perdez la connexion, le processus client meurt pendant que le gestionnaire de terminaux continue de vivre. Screen a un support spécifique à rattacher plus tard au processus de gestion des terminaux, et je ne pense pas que ce soit possible dans le cas général.

Hlovdal
la source
Merci. C'est à peu près ce à quoi je m'attendais. Voyons voir si quelqu'un peut nous prouver le contraire. ;)
John Gardeniers
J'ai appris depuis la rédaction de cette réponse qu'il existe un programme reptyr pour les processus de «repeuplement». Donc en théorie faisable, mais je pense toujours que la réponse globale ne l'est probablement pas.
hlovdal
1

retty pourrait être en mesure de vous aider, mais les clauses de non-responsabilité sont très réelles et pertinentes :)

Evan Broder
la source
1

Si la session est abandonnée, cela signifie que TTL est déjà expiré, donc il n'y a plus de tty pour vous (si je comprends bien). Mais, si votre connexion réseau est interrompue, votre session SSH peut ne pas avoir besoin de s'arrêter, et vous devriez pouvoir reprendre votre connexion et continuer. C'est de cela que vous parlez?

monomyth
la source
Je demandais en général, mais je suis surtout intéressé par le moment où un problème de réseau entraîne une perte de connexion. Dans l'ensemble, je dirais que ce n'est pas trop beau. Pourtant, cela n'a été demandé que par curiosité, plutôt que par besoin. Il est toujours agréable de connaître la réponse avant d'en avoir besoin. ;)
John Gardeniers
une connexion interrompue n'est pas un concept aussi simple qu'il n'y paraît. Vous pouvez en vivre plusieurs étapes différentes. Par exemple, vous devriez pouvoir débrancher votre câble réseau, le rebrancher dans quelques secondes et votre session SSH restera active, vous n'aurez pas à vous reconnecter pour continuer, même si vous risquez de rencontrer un court délai initial. Si vous vous retrouvez avec une session ssh tuée, cela signifie que quelque chose est mal configuré (ou plutôt pas configuré correctement pour prendre en charge ce type de perturbation).
monomyth
0

Il y avait un lien vers un code de vol hacky tty dans cette question . Vous devriez théoriquement être en mesure de l'utiliser pour reprendre le contrôle d'un processus nohup.

Kamil Kisiel
la source
1
La commande désavouée mentionnée dans les réponses à cette question mérite également d'être approfondie. Merci.
John Gardeniers