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