В
ssh host tail -f file
ssh
Клиент подключается к sshd
серверу на host
через соединение TCP. sshd
работает tail -f
со своим stdout, перенаправленным на канал. sshd
читает то, что приходит с другого конца канала, и инкапсулирует его в протокол sshd для отправки ssh
клиенту. (с помощью rshd
, tail
stdout был бы сокетом напрямую, но sshd
добавляет шифрование и может мультиплексировать несколько потоков (например, для перенаправления порта / агента / X11 / tunnel, stderr) в одном соединении TCP, поэтому приходится прибегать к каналам).
Когда вы нажимаете CTRL-C, SIGINT отправляется ssh
клиенту. Это вызывает ssh
смерть. После смерти TCP-соединение закрывается. И поэтому, на host
, sshd
плашки , а также. tail
не убит, но его стандартный вывод теперь труба без читателя на другом конце. Таким образом, в следующий раз, когда он что-то пишет в свой стандартный вывод, он получит SIGPIPE и умрет.
В:
ssh -t host 'tail -f file'
Это то же самое, за исключением того, что вместо канала используется связь между псевдотерминалом sshd
и tail
через него. tail
Stdout - это подчиненный псевдотерминал (например /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