Pourquoi SSH -t n'attend-il pas les processus d'arrière-plan?


13

Pourquoi ssh -tn'attend-il pas la fin des travaux d'arrière-plan?

Exemple:

ssh user@example 'sleep 2 &'

Cela fonctionne comme prévu, car ssh revient après 2 secondes, tandis que

ssh user@example -t 'sleep 2 &'

n'attend pas la sleepfin et revient immédiatement.

Quelqu'un peut-il expliquer la raison derrière cela? Existe-t-il un moyen d' ssh -tattendre la fin de tous les processus d'arrière-plan avant de revenir?

Mon cas d'utilisation est que je démarre un script avec ssh -t, et ce script démarre plusieurs tâches d'arrière-plan qui devraient rester en vie après la fin du script principal. Avec ssh -tcela n'est pas possible jusqu'à présent.

Réponses:


22

Sans -t, sshdobtient la sortie standard du shell distant (et des enfants comme sleep) et stderr via deux canaux (et envoie également l'entrée du client via un autre canal).

sshd attend le processus dans lequel il a démarré le shell de connexion de l'utilisateur, mais aussi, après la fin de ce processus, attend eof sur le canal stdout (pas le canal stderr dans le cas de openssh au moins).

Et eof se produit lorsqu'il n'y a pas de descripteur de fichier par un processus ouvert à la fin de l'écriture du canal, ce qui ne se produit généralement que lorsque tous les processus qui n'ont pas redirigé leur stdout vers autre chose ont disparu.

Lorsque vous utilisez -t, sshdn'utilise pas de tuyaux. Au lieu de cela, toutes les interactions (stdin, stdout, stderr) avec le shell distant et ses enfants se font à l'aide d'une paire pseudo-terminale.

Avec une paire pseudo-terminale, pour sshdinteragir avec le côté maître, il n'y a pas de traitement eof similaire ni aucun moyen de savoir s'il y a encore des processus avec des fds ouverts du côté esclave du pseudo-terminal, donc il attend juste la fin de le processus dans lequel il a exécuté le shell de connexion de l'utilisateur distant, puis se termine.

À cette sortie, le côté maître de la paire pty est fermé, ce qui signifie que le pty est détruit, de sorte que les processus contrôlés par l'esclave recevront un SIGHUP (qui, par défaut, les mettrait fin).


1
merci pour la réponse complète! une autre chose que je voudrais savoir: tous les processus d'arrière-plan se terminent-ils une fois que le pseudo-terminal se termine? le script que je démarre démarre un service, qui fonctionne bien avec ssh. mais lors de l'utilisation de ssh -t, le service n'est pas démarré. il semble que le service s'arrête une fois que ssh revient.
Philipp Murry

En fait, il existe un moyen pour le côté maître d'un pseudo-terminal de savoir quand tous les descripteurs de fichiers esclaves ont été fermés. C'est le même mécanisme déclenché par un vrai terminal lorsque tous les descripteurs de fichiers ont été fermés, en fait.
JdeBP


@JdeBP, voudriez-vous vous développer? Je ne sais pas ce que tu veux dire. Les émulateurs de terminaux AFAICT (xterm et gnome-terminal au moins) ne se soucient pas des processus ayant encore ouvert des fds à l'esclave lorsque le processus qu'ils ont exécuté le shell en meurt
Stéphane Chazelas

@PhilippMurry Vous pouvez utiliser nohuppour garder un script en cours d'exécution comme ça. (Vous pouvez également envisager de démarrer des travaux de longue durée à l'intérieur de tmuxafin de pouvoir surveiller leur progression de manière interactive, mais un fichier journal fonctionne
correctement

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.