В
ssh host tail -f file
ssh
Клієнт підключається до sshd
сервера на host
за допомогою бездротової технології TCP. sshd
проходить tail -f
зі своїм виступом, перенаправленим на трубу. sshd
читає, що надходить з іншого кінця труби, і інкапсулює його в протокол sshd для надсилання ssh
клієнту. (з rshd
, tail
stdout був би сокетом безпосередньо, але sshd
додає шифрування і може мультиплексувати декілька потоків (наприклад, для переходу на порт / агент / X11 / тунель, stderr) на одному TCP-з'єднанні, тому доводиться вдаватися до труб).
Коли ви натискаєте CTRL-C, ssh
клієнту надсилається SIGINT . Це змушує ssh
померти. Після відмирання TCP-з'єднання закривається. А отже, host
і sshd
вмирає. tail
не вбита, але тепер її виступ - це труба без читача на іншому кінці. Отже, наступного разу, коли він щось напише до свого stdout, він отримає ПІДПИС і помре.
В:
ssh -t host 'tail -f file'
Це те саме, за винятком того, що замість того, щоб бути з трубою, зв'язок між sshd
і tail
здійснюється через псевдотермінал. tail
's stoutout' є псевдо-терміналом рабовласницького типу (як /dev/pts/12
) і що б tail
там не read
було написано на головній стороні (можливо, модифікованій дисципліною Tty line), sshd
надісланим інкапсульованим ssh
клієнтом.
На стороні клієнта, з -t
, ssh
переводить термінал в raw
режим. Зокрема, це вимикає канальний режим терміналу та обробку сигналу терміналу.
Отже, коли ви натискаєте Ctrl+Cзамість термінальної лінії клієнтської лінії, що надсилає SIGINT на ssh
завдання, він просто надсилає ^C
персонажа через з'єднання sshd
і sshd
записує ^C
його на головну сторону віддаленого терміналу. І дисципліна лінії віддаленого терміналу посилає SIGINT
на tail
. tail
потім помирає, sshd
виходить і закриває з'єднання та ssh
припиняється (якщо воно іншим чином ще не зайняте переадресацією портів чи іншим).
Також, -t
якщо ssh
клієнт помирає (наприклад, якщо ви входите ~.
), з'єднання закривається і sshd
відмирає. Як результат, SIGHUP буде надісланий на tail
.
Тепер будьте уважні, що використання -t
має побічні ефекти. Наприклад, з налаштуваннями терміналу за замовчуванням \n
символи перетворюються на \r\n
інші речі, і це може траплятися більше, залежно від віддаленої системи, тому ви, можливо, захочете видати stty -opost
(відключити післяобробну обробку виводу) на віддаленому хості, якщо цей вихід не призначений для термінал:
$ 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
Ще одним недоліком використання -t
/ -tt
є те, що stdout та stderr не відрізняються від клієнта. І stdout, і stderr віддаленої команди будуть записані в ssh
stdout клієнта:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1