web-dev-qa-db-fra.com

La déconnexion d'une session SSH tue-t-elle vos programmes?

Donc, disons que je suis déconnecté d'une session SSH après avoir démarré rsync ou cp ou toute autre commande qui peut durer longtemps. Est-ce que cette commande continue de fonctionner jusqu'à ce qu'elle soit terminée après que je me suis déconnecté ou est-elle simplement tuée?

Je me suis toujours demandé cela.

92
fregas

Modifier pour 2016:

Cette Q&R est antérieure à la débâcle systemd v2 . À partir de systemd v230, la nouvelle valeur par défaut est de tuer tous les enfants d'une session de connexion qui se termine, quelles que soient les précautions historiquement valides prises pour éviter cela. Le comportement peut être modifié en définissant KillUserProcesses=no dans /etc/systemd/logind.conf, ou contourné 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 comment les choses fonctionnent traditionnellement dans l'espace de conception UNIX depuis plus longtemps que Linux.


Ils seront tués, mais pas nécessairement immédiatement. Cela dépend du temps qu'il faut au 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 alloué un pseudo-terminal et l'a attaché au shell de connexion configuré de votre utilisateur. C'est ce qu'on appelle le terminal de contrôle. Chaque programme que vous démarrez normalement à ce stade, quel que soit le nombre de couches de coquilles profondes, retracera finalement son ascendance jusqu'à cette coquille. Vous pouvez observer cela avec la commande pstree.

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 après lui-même. Ce qui se passe à ce stade est spécifique à Shell (recherchez "HUP" dans sa page de documentation), mais pour la plupart, il commencera à envoyer SIGHUP aux travaux en cours d'exécution qui lui sont associés avant de se terminer. Chacun de ces processus, à son tour, fera tout ce qu'il est configuré pour faire à la réception de ce signal. Habituellement, cela signifie mettre fin. Si ces emplois ont leur propre emploi, le signal sera souvent transmis également.

Les processus qui survivent à un blocage du terminal de contrôle sont ceux qui se dissocient d'avoir un terminal (processus démon que vous avez démarrés à l'intérieur de celui-ci) ou ceux qui ont été invoqués avec une commande Nohup préfixée. (c'est-à-dire "ne raccrochez pas") Les démons interprètent différemment le signal HUP; comme ils n'ont pas de terminal de contrôle et ne reçoivent pas automatiquement un signal HUP, il est à la place réutilisé comme une demande manuelle de l'administrateur pour recharger la configuration. Ironiquement, cela signifie que la plupart des administrateurs n'apprennent l'utilisation du "raccrochage" de ce signal pour les non-démons que bien plus tard. Voilà pourquoi vous lisez ceci!

Les multiplexeurs de terminaux sont un moyen courant de conserver votre environnement Shell intact entre les déconnexions. Ils vous permettent de vous détacher de vos processus Shell de manière à pouvoir les rattacher ultérieurement, que cette déconnexion soit accidentelle ou délibérée. tmux et screen sont les plus populaires; la syntaxe pour les utiliser est au-delà de la portée de votre question, mais elles méritent d'être examinées.


Il m'a été demandé de préciser le temps qu'il faut au démon SSH pour décider 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 chacun d'eux pour se terminer lorsque l'un ou l'autre côté réinitialise la connexion TCP. Cela se produira rapidement si le serveur tente pour écrire sur le socket et les paquets TCP ne sont pas reconnus, ou lentement si rien n'essaye d'écrire sur le PTY.

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

  • Processus (généralement celui du premier plan) tentant d'écrire sur le PTY côté serveur. (serveur-> client)
  • L'utilisateur tente d'écrire dans le PTY côté client. (client-> serveur)
  • Keepalives de toute sorte. Ceux-ci ne sont généralement pas activés par défaut, ni par le client ni par le serveur, et il existe généralement deux versions: niveau application et TCP basé (c'est-à-dire SO_KEEPALIVE). Les Keepalives reviennent au serveur ou au client à envoyer rarement des paquets de l'autre côté, même lorsque rien n'aurait autrement une raison d'écrire dans le socket. Bien que cela soit généralement destiné à contourner les pare-feu qui expirent trop rapidement les connexions, cela a pour effet secondaire supplémentaire de faire en sorte que l'expéditeur remarque lorsque l'autre côté ne répond pas beaucoup plus rapidement.

Les règles habituelles pour les sessions TCP s'appliquent ici: s'il y a une interruption de la connectivité entre le client et le serveur, mais qu'aucun des deux côtés n'essaie d'envoyer un paquet pendant le problème, la connexion survivra à condition que les deux les parties réagissent ensuite et reçoivent les numéros de séquence attendus TCP.

Si un côté a décidé que le socket est mort, les effets sont généralement immédiats: le processus sshd enverra HUP et se terminera automatiquement (comme décrit précédemment), ou le client notifiera à l'utilisateur le problème détecté. Il convient de noter que ce n'est pas parce qu'un côté pense que l'autre est mort que cela a été notifié à l'autre. Le côté orphelin de la connexion restera généralement ouvert jusqu'à ce qu'il essaie d'y écrire et expire, ou reçoive une TCP réinitialisation de l'autre côté. (Si la connectivité était disponible à l'époque) Le nettoyage décrit dans cette réponse ne se produit qu'une fois que le serveur l'a remarqué.

120
Andrew B

Comme d'autres l'ont mentionné, une fois que vous vous déconnectez de ssh, tout ce qui s'y déroule a disparu.

Comme @ Michael Hampton et d'autres l'ont mentionné, vous pouvez utiliser des outils comme tmux ou screen pour vous déconnecter/reconnecter aux terminaux sans perdre leur contenu (c'est-à-dire les processus enfants).

De plus, vous pouvez mettre un processus en arrière-plan à l'aide d'une esperluette & puis utilisez la commande disown pour 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
%
23
slm

Non, tout programme encore attaché au terminal, et non placé en arrière-plan avec quelque chose comme Nohup, serait tué.

C'est pourquoi il existe des solutions de terminaux virtuels comme tmux et les anciennes screen qui créent des sessions qui continuent de s'exécuter même si vous êtes déconnecté et auxquelles vous pouvez vous rattacher plus tard.

14
Michael Hampton