Em
ssh host tail -f file
O cliente ssh conecta-se ao servidor sshd em host em uma conexão TCP. sshd runs tail -f com seu stdout redirecionado para um pipe. sshd lê o que vem da outra extremidade do encapsulamento e o encapsula no protocolo sshd para enviar para o cliente ssh . (com rshd , tail stdout teria sido o soquete diretamente, mas sshd adiciona criptografia e é capaz de multiplexar vários fluxos (como para redirecionamento de porta / agente / X11 / túnel, stderr) em uma única conexão TCP tem que recorrer a tubos).
Quando você pressiona CTRL-C, uma SIGINT é enviada ao cliente ssh . Isso faz com que ssh morra. Ao morrer, a conexão TCP é fechada. E, portanto, em host , sshd também morre. tail não é morto, mas seu stdout é agora um pipe sem leitor na outra extremidade. Então, da próxima vez que escrever algo em seu stdout, ele receberá um SIGPIPE e morrerá.
Em:
ssh -t host 'tail -f file'
É a mesma coisa, exceto que, em vez de estar com um pipe, a comunicação entre sshd e tail é feita por meio de um pseudo-terminal. O stdout de tail é um pseudo-terminal escravo (como /dev/pts/12 ) e qualquer que seja o tail escreve existe read no lado mestre (possivelmente modificado pela tty line disciplina) por sshd e enviado encapsulado para o cliente ssh .
No lado do cliente, com -t , ssh coloca o terminal no modo raw . Em particular, isso desativa o modo canônico do terminal e o manuseio do sinal do terminal.
Então, quando você pressiona Ctrl + C , ao invés da disciplina de linha de terminal do cliente enviar uma SIGINT para o trabalho ssh , isso apenas envia o caractere ^C sobre a conexão para sshd e sshd escreve que ^C para o lado mestre do terminal remoto. E a disciplina de linha do terminal remoto envia um SIGINT para tail . tail então morre, e sshd sai e fecha a conexão e ssh termina (se ainda não estiver ocupado com encaminhamentos de porta ou outros).
Além disso, com -t , se o cliente ssh morrer (por exemplo, se você inserir ~. ), a conexão será fechada e sshd será interrompido. Como resultado, um SIGHUP será enviado para tail .
Agora, esteja ciente de que usar -t tem efeitos colaterais. Por exemplo, com as configurações padrão do terminal, \n caracteres são convertidos em \r\n e mais coisas podem acontecer dependendo do sistema remoto, então você pode querer emitir um stty -opost (para desabilitar o pós-processamento de saída) no host remoto se essa saída não for destinada a um 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
Outra desvantagem de usar -t / -tt é que stdout e stderr não são diferenciados no cliente. O stdout e o stderr do comando remoto serão gravados no stdout do ssh 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