Être déconnecté d'une session SSH tue-t-il vos programmes?

89

Alors, dis - je suis déconnecté d'une session SSH après que j'ai commencé rsyncou cpou toute autre commande qui peut être long cours d' exécution. Cette commande continue-t-elle à fonctionner jusqu'à ce qu'elle soit terminée après ma déconnexion ou est-elle simplement mise à mort?

Toujours demandé cela.

Fregas
la source
Je veux juste ajouter à ce qui a été dit plus haut que si vous vous trouvez dans une situation où vous devez mettre un processus déjà en cours screen, essayez reptyr .
Un mec triste
Cela tuera vos programmes. Très ennuyeux si vous mettez à jour la version du système d'exploitation de Ubuntu 16.04 à 17.10 via SSH
kurdtpage

Réponses:

118

Éditer pour 2016:

Cette période de questions précède la débâcle de Systemd v230 . Depuis systemd v230, la nouvelle valeur par défaut consiste à tuer tous les enfants d'une session de connexion qui se termine, quelles que soient les précautions historiquement valables prises pour empêcher cela. Le comportement peut être modifié par la mise KillUserProcesses=noen /etc/systemd/logind.confou contournée en utilisant les mécanismes spécifiques à systemd pour démarrer un démon dans l' espace utilisateur. Ces mécanismes sortent du cadre de cette question.

Le texte ci-dessous décrit la manière dont les choses ont toujours fonctionné dans UNIX Designspace plus longtemps que Linux n’existe.


Ils seront tués, mais pas nécessairement immédiatement. Cela dépend du temps que prend le démon SSH pour décider que votre connexion est morte. Ce qui suit est une explication plus longue qui vous aidera à comprendre comment cela fonctionne réellement.

Lorsque vous vous êtes connecté, le démon SSH vous a attribué un pseudo-terminal et l'a connecté au shell de connexion configuré de votre utilisateur. Ceci est appelé le terminal de contrôle. Tous les programmes que vous démarrez normalement à ce stade, quel que soit le nombre de couches de coquilles profondes, retrouveront leur origine dans cette coquille. Vous pouvez l'observer avec la pstreecommande.

Lorsque le processus démon SSH associé à votre connexion décide que votre connexion est morte, il envoie un signal de raccrochage ( SIGHUP) au shell de connexion. Cela informe le shell que vous avez disparu et qu'il devrait commencer à se nettoyer. Ce qui se passe à ce stade est spécifique au shell (recherchez "HUP" dans la page de documentation), mais la plupart du temps, il commencera à envoyer SIGHUPles travaux en cours qui lui sont associés avant de se terminer. Chacun de ces processus, à son tour, fera ce qu'il est configuré pour faire à la réception de ce signal. Habituellement, cela signifie la fin. Si ces emplois ont des emplois propres, le signal sera également transmis.

Les processus qui survivent à un raccrochage du terminal de contrôle sont ceux qui se sont dissociés d'un terminal (processus de démon que vous avez démarrés à l'intérieur de celui-ci) ou ceux qui ont été appelés avec une nohupcommande préfixée . (c'est-à-dire "ne raccrochez pas"). Les démons interprètent le signal HUP différemment. Comme ils ne possèdent pas de terminal de contrôle et ne reçoivent pas automatiquement un signal HUP, celui-ci est réaffecté sous la forme d'une demande manuelle de l'administrateur pour recharger la configuration. Ironiquement, cela signifie que la plupart des administrateurs n’apprennent l’utilisation du "blocage" de ce signal pour les non-démons que beaucoup plus tard. C'est pourquoi vous lisez ceci!

Les multiplexeurs de terminaux sont un moyen courant de garder votre environnement shell intact entre les déconnexions. Ils vous permettent de vous détacher de vos processus shell de manière à pouvoir vous reconnecter ultérieurement, que cette déconnexion soit accidentelle ou délibérée. tmuxet screensont les plus populaires; La syntaxe pour les utiliser va au-delà de la portée de votre question, mais elles méritent d'être explorées.


Il a été demandé que je précise dans combien de temps le démon SSH décide que votre connexion est morte. Il s'agit d'un comportement spécifique à chaque implémentation d'un démon SSH, mais vous pouvez compter sur chacune d'entre elles pour se terminer lorsque l'un ou l'autre côté réinitialise la connexion TCP. Cela se produira rapidement si le serveur tente d'écrire sur le socket et si les paquets TCP ne sont pas reconnus, ou lentement si rien ne tente d'écrire sur le PTY.

Dans ce contexte particulier, les facteurs les plus susceptibles de déclencher une écriture sont les suivants:

  • Un processus (généralement celui du premier plan) qui tente d’écrire sur le PTY côté serveur. (serveur-> client)
  • L'utilisateur essayant d'écrire sur le PTY côté client. (client-> serveur)
  • Keepalives de toute sorte. Celles-ci ne sont généralement pas activées par défaut, que ce soit par le client ou le serveur, et il existe généralement deux types: le niveau de l'application et le protocole TCP (c. SO_KEEPALIVE-à-d.). Keepalives revient au serveur ou au client qui envoie rarement des paquets à l’autre côté, même lorsque rien n’aurait autrement une raison d’écrire dans le socket. Bien que cela ait généralement pour but de contourner les pare-feu qui expirent trop rapidement les connexions, cela a également pour effet secondaire de faire en sorte que l'expéditeur remarque que l'autre côté ne répond pas plus rapidement.

Les règles habituelles pour les sessions TCP s'appliquent ici: en cas d'interruption de la connectivité entre le client et le serveur, mais si aucun des deux camps ne tente d'envoyer un paquet pendant le problème, la connexion survivra à condition que les deux côtés réagissent ensuite et reçoivent le protocole TCP attendu. numéros de séquence.

Si une partie a décidé que le socket est mort, les effets sont généralement immédiats: le processus sshd envoie HUPet se termine automatiquement (comme décrit précédemment), ou le client informe l'utilisateur du problème détecté. Il convient de noter que le fait que l'une des parties pense que l'autre est mort ne signifie pas que l'autre a été averti de cela. Le côté orphelin de la connexion reste généralement ouvert jusqu'à ce qu'il tente d'écrire et expire ou qu'il reçoive une réinitialisation TCP de l'autre côté. (si la connectivité était disponible à ce moment-là) Le nettoyage décrit dans cette réponse ne se produit que lorsque le serveur l’ a remarqué.

Andrew B
la source
3
J'ajouterais également la commande "dtach" à cette liste - c'est un peu l'opposé de screen / tmux en ce sens qu'elle vous permet d'attacher plusieurs terminaux à une seule session et qu'elle est également très utile pour prolonger une session, bien que cela ne soit pas le cas. fournir aucun moyen de rejouer l'histoire récente.
moelleux
dtachl'URL est ici: dtach.sourceforge.net
slm
2
excellente explication. Je me sens déjà plus linuxey!
Fregas
3
En outre, bien que cela ne fasse pas techniquement partie de votre réponse, voici une petite anecdote intéressante: vous pouvez l'utiliser kill -HUPcomme racine pour forcer le terminal de quelqu'un à raccrocher. Vous ne devriez pas faire cela sans bonne raison. Je tire le meilleur parti de mon kilométrage lorsque les utilisateurs laissent les shells en cours d'exécution pendant la maintenance et que je dois démonter un système de fichiers que leur shell maintient ouvert. Si l'utilisateur est connecté mais qu'il est à l'arrêt, envoyez le signal à son processus sshd. Sinon, s'il fonctionne à l'intérieur d'un multiplexeur de terminal, envoyez-le au shell que vous souhaitez arrêter. Ne raccrochez que la coquille pour vous empêcher de travailler!
Andrew B
@ AndrewB, pourriez-vous s'il vous plaît préciser comment "le processus du démon SSH ... décide que votre connexion est morte"? Et comment puis-je savoir si le démon SSH pense / sait que la connexion (quelle) est morte ou non?
Xiao Peng - ZenUML.com
22

Comme d'autres l'ont mentionné, une fois que vous vous êtes déconnecté de ssh, tout ce qui s'y trouve est parti.

Comme @Michael Hampton et d'autres l'ont mentionné, vous pouvez utiliser des outils tels que tmuxou screenpour déconnecter / reconnecter des terminaux sans perdre leur contenu (par exemple, des processus enfants).

De plus, vous pouvez mettre un processus en arrière-plan à l'aide d'une esperluette &, puis utiliser la commande disownpour les dissocier du shell actuel.

# start a command
% sleep 5000 &
[1] 3820

# check it
% jobs
[1]+  Running                 sleep 5000 &

# disown everything
% disown -a

# check it again (gone from shell)
% jobs
%

# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml      3820 23791  0 00:16 pts/1    00:00:00 sleep 5000
%
slm
la source
Est-il possible de rattacher une session de terminal à un disownprocessus ed?
Faux nom
4
Oui. Consultez cette question U & L pour plus de détails: unix.stackexchange.com/questions/4034/…
slm
13

Non, tous les programmes encore attachés au terminal, et non placés en arrière-plan avec quelque chose comme nohup, seraient tués.

C’est la raison pour laquelle il existe des solutions de terminal virtuel, comme tmuxles anciennes, screenqui créent des sessions qui continuent de fonctionner même si vous êtes déconnecté et sur lesquelles vous pouvez vous reconnecter ultérieurement.

Michael Hampton
la source