В
ssh host tail -f file
sshКлиент подключается к sshdсерверу на hostчерез соединение TCP. sshdработает tail -fсо своим stdout, перенаправленным на канал. sshdчитает то, что приходит с другого конца канала, и инкапсулирует его в протокол sshd для отправки sshклиенту. (с помощью rshd, tailstdout был бы сокетом напрямую, но sshdдобавляет шифрование и может мультиплексировать несколько потоков (например, для перенаправления порта / агента / X11 / tunnel, stderr) в одном соединении TCP, поэтому приходится прибегать к каналам).
Когда вы нажимаете CTRL-C, SIGINT отправляется sshклиенту. Это вызывает sshсмерть. После смерти TCP-соединение закрывается. И поэтому, на host, sshdплашки , а также. tailне убит, но его стандартный вывод теперь труба без читателя на другом конце. Таким образом, в следующий раз, когда он что-то пишет в свой стандартный вывод, он получит SIGPIPE и умрет.
В:
ssh -t host 'tail -f file'
Это то же самое, за исключением того, что вместо канала используется связь между псевдотерминалом sshdи tailчерез него. tailStdout - это подчиненный псевдотерминал (например /dev/pts/12), и все tailзаписи, которые есть readна главной стороне (возможно, модифицированные дисциплиной линии tty), 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 не различаются на клиенте. И стандартный вывод, и стандартный вывод удаленной команды будут записаны в стандартный sshвывод клиента:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1