Dans
ssh host tail -f file
Le ssh
client se connecte au sshd
serveur host
via une connexion TCP. sshd
s'exécute tail -f
avec sa sortie standard redirigée vers un tuyau. sshd
lit ce qui vient de l'autre extrémité du tube et l'encapsule dans le protocole sshd pour l'envoyer au ssh
client. (avec rshd
, tail
stdout aurait été le socket directement, mais sshd
ajoute un chiffrement et est capable de multiplexer plusieurs flux (comme pour la redirection de port / agent / X11 / tunnel, stderr) sur une seule connexion TCP et doit donc recourir à des canaux).
Lorsque vous appuyez sur CTRL-C, un SIGINT est envoyé au ssh
client. Cela fait ssh
mourir. En mourant, la connexion TCP est fermée. Et donc, le host
, sshd
meurt aussi. tail
n'est pas tué, mais sa sortie standard est maintenant une pipe sans lecteur à l'autre bout. Ainsi, la prochaine fois qu'il écrit quelque chose sur sa sortie standard, il recevra un SIGPIPE et mourra.
Dans:
ssh -t host 'tail -f file'
C'est la même chose sauf qu'au lieu d'être avec une pipe, la communication entre sshd
et se tail
fait via un pseudo-terminal. tail
La sortie standard est un pseudo-terminal esclave (comme /dev/pts/12
) et quelle que soit l' tail
écriture read
du côté maître (éventuellement modifiée par la discipline de ligne tty) par sshd
et envoyée encapsulée au ssh
client.
Côté client, avec -t
, ssh
met le terminal en raw
mode. En particulier, cela désactive le mode canonique du terminal et la gestion du signal du terminal.
Ainsi, lorsque vous appuyez sur Ctrl+C, au lieu que la discipline de ligne de terminal du client envoie un SIGINT au ssh
travail, cela envoie simplement le ^C
caractère sur la connexion sshd
et l' sshd
écrit ^C
sur le côté maître du terminal distant. Et la discipline de ligne du terminal distant envoie un SIGINT
à tail
. tail
puis meurt, sshd
quitte et ferme la connexion et se ssh
termine (si elle n'est pas autrement encore occupée avec les transferts de port ou autre).
De plus, avec -t
, si le ssh
client meurt (par exemple si vous entrez ~.
), la connexion est fermée et sshd
meurt. En conséquence, un SIGHUP sera envoyé à tail
.
Maintenant, sachez que l'utilisation -t
a des effets secondaires. Par exemple, avec les paramètres de terminal par défaut, les \n
caractères sont convertis en \r\n
et plus de choses peuvent se produire en fonction du système distant, vous pouvez donc vouloir émettre un stty -opost
(pour désactiver le post-traitement de sortie) sur l'hôte distant si cette sortie n'est pas destinée à un terminal:
$ ssh localhost 'echo x' | hd
00000000 78 0a |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000 78 0d 0a |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000 78 0a |x.|
00000002
Un autre inconvénient de l'utilisation de -t
/ -tt
est que stdout et stderr ne sont pas différenciés sur le client. Le stdout et le stderr de la commande à distance seront écrits sur le ssh
stdout du client:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1
-t
, si lessh
client décède (par exemple si vous entrez~.
)" Qu'est-ce que c'est~.
encore?~.
est la séquence d'échappement que vous entrez pour déconnecter le client. Voirman ssh
pour plus de détails.Vous avez besoin d'une allocation de terminal du côté distant:
ou même
la source
-t
ou-tt
ça marche. Mais je ne comprends toujours pas la vraie raison de ceci: disons, quand j'appelle le shell à distance et ferme la connexion, le shell est terminé. Maistail -f
non. Bien sûr, j'ai déjà lu l'-t
optionman ssh
, mais cela n'a pas beaucoup aidé. Il semble que je ne comprenne pas certains génériques, et je serais heureux si vous suggériez des documents à lire à ce sujet, ou probablement l'expliquez vous-même. Merci!sshd
envoie unSIGHUP
. Mais là où il n'y a pas de terminal, il ne peut y avoir de blocage de connexion de terminal ...SIGHUP
et d'autres signaux, je ne sais toujours presque rien à ce sujet.tail -f
, puis je l'ai ouverthtop
et envoyéSIGHUP
(en appuyant surF9
->1
->Enter
), ettail -f
c'est terminé! Donc, la raison devrait être différente ..tail
ne réagirait pasSIGHUP
. Le problème est queSIGHUP
** n'est pas envoyé àtail
sans pseudo-terminal. Vous pouvez le voir en l'attachantstrace
àtail
dans les deux cas.