W
ssh host tail -f file
sshKlient łączy się z sshdserwerem na hostpośrednictwem połączenia TCP. sshddziała tail -fz przekierowaniem standardu na potok. sshdodczytuje to, co pochodzi z drugiego końca potoku i hermetyzuje go w protokole sshd, aby wysłać do sshklienta. (z rshd, tailstdout byłby bezpośrednio gniazdem, ale sshddodaje szyfrowanie i jest w stanie multipleksować kilka strumieni (jak dla przekierowania portu / agenta / X11 / tunelu, stderr) na jednym połączeniu TCP, więc musi uciekać się do potoków).
Po naciśnięciu CTRL-C do sshklienta wysyłany jest SIGINT . To powoduje sshśmierć. Po śmierci połączenie TCP zostaje zamknięte. A zatem host, sshdmatryce, jak również. tailnie jest zabity, ale jego stdout jest teraz rurą bez czytnika na drugim końcu. Tak więc, następnym razem, gdy napisze coś na swoje standardowe wyjście, otrzyma SIGPIPE i umrze.
W:
ssh -t host 'tail -f file'
To to samo, z tą różnicą, że zamiast być z potokiem komunikacja między sshdi tailodbywa się za pośrednictwem pseudo-terminala. tailstdout jest pseudo-terminalem slave (podobnym /dev/pts/12) i cokolwiek tailzapisuje readsię po stronie master (być może zmodyfikowane przez dyscyplinę linii tty) sshdi wysyłane jest do enkapsulacji do sshklienta.
Po stronie klienta -t, sshprzełącza terminal w rawtryb. W szczególności wyłącza to tryb kanoniczny terminala i obsługę sygnału terminala.
Tak więc, gdy naciśniesz Ctrl+C, zamiast dyscypliny linii terminalu klienta wysyłającej SIGINT do sshzadania, to po prostu wysyła ^Cznak przez połączenie sshdi sshdzapisuje go ^Cdo strony głównej zdalnego terminala. A dyscyplina liniowa zdalnego terminala wysyła SIGINTdo tail. tailnastępnie umiera, sshdopuszcza i zamyka połączenie i sshprzerywa połączenie (jeśli nie jest zajęte przekazywaniem portów lub innymi).
Ponadto, -tjeśli sshklient umrze (na przykład jeśli wejdziesz ~.), połączenie zostanie zamknięte i sshdumrze. W rezultacie SIGHUP zostanie wysłany do tail.
Teraz uważaj, że używanie -tma skutki uboczne. Na przykład przy domyślnych ustawieniach terminala \nznaki są konwertowane na \r\ni w zależności od systemu zdalnego może się zdarzyć więcej rzeczy, więc możesz chcieć wydać stty -opost(aby wyłączyć przetwarzanie końcowe danych wyjściowych) na zdalnym hoście, jeśli dane wyjściowe nie są przeznaczone 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
Kolejną wadą używania -t/ -ttjest to, że stdout i stderr nie są zróżnicowane na kliencie. Zarówno stdout, jak i stderr polecenia zdalnego zostaną zapisane sshna stdout klienta:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1