Les programmes exécutés à partir d'une session ssh dépendent-ils de la connexion?

29

Un programme exécuté à partir d'une session ssh dépend-il de la connexion au client? Par exemple lorsque la connexion est vraiment lente. Attend-il donc activement que les choses soient imprimées à l'écran?

Et si cela dépend de la connexion, cela se produit-il également avec screen ou byobu par exemple? Puisqu'avec ces derniers, les programmes continuent de fonctionner même après la déconnexion de l'hôte.


Remarque: je n'ai trouvé que ces questions connexes:

agold
la source
1
Notez que si votre connexion est perdue, le programme continuera de fonctionner jusqu'à l'expiration de la session (sauf s'il est bloqué dans une opération d'impression), mais si votre session se termine, le programme se terminera normalement.
Sebb

Réponses:

26

La sortie des programmes est mise en mémoire tampon, donc si la connexion est lente, le programme sera interrompu si la mémoire tampon se remplit.

Si vous utilisez screen, il a également un tampon qu'il utilise pour essayer d'afficher sur une session connectée. Mais un programme connecté dans la session écran ne sera pas arrêté s'il screenne peut pas mettre à jour le terminal distant assez rapidement. Tout comme lorsqu'une connexion est perdue, le programme continue de remplir le screenstampon jusqu'à ce qu'il déborde (en poussant les informations les plus anciennes). Ce que vous voyez arriver (et pouvez revenir en arrière) dépend de ce qui est (toujours) dans ce tampon. screendissocie efficacement votre programme de votre terminal (et de votre connexion SSH lente).

Anthon
la source
9

Une connexion SSH peut mourir prématurément si la connexion TCP sous-jacente reçoit un paquet avec l' indicateur RST . Cela pourrait se produire si un côté envoie un paquet (qui pourrait être une sonde SSH périodique) mais ne reçoit pas d'accusé de réception TCP dans un délai raisonnable, ou si un routeur décide que la connexion est restée inactive trop longtemps, ou si un FAI est simplement méchant.

Dans le modèle de terminal Unix, lorsque la connexion du terminal est interrompue, le pilote de terminal envoie un signal HUP au shell, dont la terminaison entraîne également l'envoi d'un SIGHUP aux processus exécutés dans le shell.

Dans la FAQ Unix Programmer , point 1.15:

SIGHUPest un signal qui signifie, par convention, "la ligne terminale a été suspendue". Il n'a rien à voir avec les processus parents et est généralement généré par le pilote tty (et remis au groupe de processus de premier plan).

Cependant, dans le cadre du système de gestion de session, il y a exactement deux cas où SIGHUPest envoyé à la mort d'un processus:

  • Lorsque le processus qui meurt est le chef de session d'une session attachée à un terminal, SIGHUPest envoyé à tous les processus du groupe de processus de premier plan de ce terminal.

  • Lorsque la mort d'un processus provoque un groupe de processus pour devenir orphelins, et un ou plusieurs processus dans le groupe sont devenus orphelins arrêté , alors SIGHUPet SIGCONTsont envoyés à tous les membres du groupe devenus orphelins. (Un groupe de processus orphelin est un groupe dans lequel aucun processus du groupe n'a un parent qui fait partie de la même session, mais pas le même groupe de processus.)

Le gestionnaire de signal par défaut pour SIGHUP consiste à terminer le processus:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

Il est cependant possible d'éviter l'arrêt du processus.

  • Vous pouvez insérer un gestionnaire de signaux qui ignore SIGHUP. Pour ce faire en tant qu'utilisateur, encapsulez la commande dans nohup. Par exemple:

    nohup make all &
    
  • Vous pouvez dire au shell de dissocier un processus enfant de celui-ci. Par exemple, Bash a une disowncommande intégrée:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Ensuite, le SIGHUP ne sera pas propagé à l'enfant (qui n'est plus un enfant).

  • Certains programmes, notamment les démons , utiliseront automatiquement les mécanismes ci-dessus: un programme peut installer un autre gestionnaire SIGHUP (en utilisant sigaction(2)), ou il pourrait choisir de rejoindre une nouvelle session ( setsid(2)).
  • Vous pouvez exécuter screenou tmux, qui alloue un pseudo-TTY pour exécuter une session avec un shell qui ne reçoit pas le SIGHUP lorsque la connexion SSH s'éteint. Le SIGHUP n'est pas relayé de la session SSH à la session screen / tmux.

Soit dit en passant, une autre façon de gérer les connexions SSH non fiables consiste à utiliser le protocole Mosh à la place. Mosh s'exécute sur UDP, il n'y a donc pas de connexion TCP qui risque d'être réinitialisée.

200_success
la source
Pour en savoir plus: Différence entre nohup, disown et & .
200_success
1

Oui, un programme exécuté sur SSH dépendra de sa sortie quelque part. Si la connexion est lente, la sortie doit être mise en mémoire tampon quelque part et les mémoires tampons ne peuvent pas être infinies, donc le programme doit bloquer s'il est rempli.

Notez que la sortie ne va pas nécessairement aller à un terminal: envisagez d'exécuter quelque chose comme

ssh user@somewhere "cat file.txt" > file.txt

Cela copiera en fait le fichier. Pour que cela fonctionne, le taux de sortie de cat doit correspondre à celui de la connexion: il devrait être évident que perdre des parties de la sortie du milieu serait inacceptable.

L'écran changera la situation en ce qu'il agira comme un terminal et enregistrera ce qui devrait être affiché "sur la fenêtre du terminal" (plus défilement arrière). Il n'a pas besoin de se souvenir de tout ce que votre programme sort, seulement des parties qui s'adapteront à la "fenêtre" et au défilement. Par défaut, l'écran attendra une connexion lente (bloquant le programme), mais il peut être configuré pour détecter une connexion bloquée en définissant "nonblock on".

Depuis la page de manuel:

nonblock [on | off | numsecs]

Dites à l'écran comment gérer les interfaces utilisateur (affichages) qui cessent d'accepter la sortie. Cela peut se produire si un utilisateur appuie sur ^ S ou si une connexion TCP / modem est coupée mais qu'aucun raccrochage n'est reçu. Si le nonbloc est désactivé (c'est la valeur par défaut), l'écran attend que l'affichage redémarre pour accepter la sortie. Si le nonbloc est activé, l'écran attend que le délai soit atteint (on est traité comme 1 s). Si l'écran ne reçoit toujours pas de caractères, l'écran le considérera comme "bloqué" et cessera de lui envoyer des caractères. Si à un moment donné il redémarre pour accepter les caractères, l'écran débloquera l'affichage et réaffichera le contenu de la fenêtre mise à jour.

Une déconnexion est différente d'une connexion lente. Plain SSH ne peut pas s'en remettre automatiquement, donc votre programme recevra un SIGHUP. D'autre part, l'écran détectera une déconnexion, se détachera et retombera dans la mise en mémoire tampon locale jusqu'à ce que l'écran soit reconnecté. Cela ne bloquera pas le programme en cours d'exécution.

(Le paramétrage nonblock 1de votre .screenrcest important si vous exécutez quelque chose comme irssi qui produira en continu une sortie mais doit toujours parler au réseau en même temps. Le blocage entraînerait la déconnexion d'IRC, ce qui est extrêmement ennuyeux ...)

ilkkachu
la source