Em
ssh host tail -f file
O sshcliente se conecta ao sshdservidor em hostuma conexão TCP. sshdé executado tail -fcom seu stdout redirecionado para um pipe. sshdlê o que está vindo da outra extremidade do pipe e o encapsula no protocolo sshd para enviar ao sshcliente. (com rshd, tailstdout teria sido o soquete diretamente, mas sshdadiciona criptografia e é capaz de multiplexar vários fluxos (como para porta / agente / X11 / redirecionamento de túnel, stderr) em uma única conexão TCP, portanto, é necessário recorrer a pipes).
Quando você pressiona CTRL-C, um SIGINT é enviado ao sshcliente. Isso causa ssha morte. Ao morrer, a conexão TCP é fechada. E, portanto, em host, sshdmorre também. tailnão é morto, mas agora o stdout é um cano 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 cano, a comunicação entre sshde tailé via pseudo-terminal. tailO stdout é um pseudo-terminal escravo (como /dev/pts/12) e qualquer tailgravação existente readno lado mestre (possivelmente modificada pela disciplina da linha tty) sshde enviada encapsulada para o sshcliente.
No lado do cliente, com -t, sshcoloca o terminal no rawmodo. Em particular, isso desativa o modo canônico do terminal e a manipulação do sinal do terminal.
Portanto, quando você pressiona Ctrl+C, em vez da disciplina da linha de terminal do cliente enviar um SIGINT para o sshtrabalho, ele envia o ^Ccaractere pela conexão sshde o sshdgrava ^Cno lado principal do terminal remoto. E a disciplina de linha do terminal remoto envia um SIGINTpara tail. tailentão morre, sshdsai e fecha a conexão e sshtermina (se ainda não estiver ocupado com o encaminhamento de porta ou outro).
Além disso, com -t, se o sshcliente morre (por exemplo, se você entrar ~.), a conexão é fechada e sshdmorre. Como resultado, um SIGHUP será enviado para tail.
Agora, tenha cuidado que o uso -ttem efeitos colaterais. Por exemplo, com as configurações padrão do terminal, os \ncaracteres são convertidos \r\ne outras coisas podem acontecer, dependendo do sistema remoto; portanto, você pode emitir um stty -opost(para desativar o pós-processamento da saída) no host remoto, se essa saída não se destina 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 sshstdout do cliente:
$ ssh localhost ls /x | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1