Em
ssh host tail -f file
O ssh
cliente se conecta ao sshd
servidor em host
uma conexão TCP. sshd
é executado tail -f
com seu stdout redirecionado para um pipe. sshd
lê o que está vindo da outra extremidade do pipe e o encapsula no protocolo sshd para enviar ao ssh
cliente. (com rshd
, tail
stdout teria sido o soquete diretamente, mas sshd
adiciona 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 ssh
cliente. Isso causa ssh
a morte. Ao morrer, a conexão TCP é fechada. E, portanto, em host
, sshd
morre também. tail
nã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 sshd
e tail
é via pseudo-terminal. tail
O stdout é um pseudo-terminal escravo (como /dev/pts/12
) e qualquer tail
gravação existente read
no lado mestre (possivelmente modificada pela disciplina da linha tty) sshd
e enviada encapsulada para o ssh
cliente.
No lado do cliente, com -t
, ssh
coloca o terminal no raw
modo. 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 ssh
trabalho, ele envia o ^C
caractere pela conexão sshd
e o sshd
grava ^C
no lado principal do terminal remoto. E a disciplina de linha do terminal remoto envia um SIGINT
para tail
. tail
então morre, sshd
sai e fecha a conexão e ssh
termina (se ainda não estiver ocupado com o encaminhamento de porta ou outro).
Além disso, com -t
, se o ssh
cliente morre (por exemplo, se você entrar ~.
), a conexão é fechada e sshd
morre. Como resultado, um SIGHUP será enviado para tail
.
Agora, tenha cuidado que o uso -t
tem efeitos colaterais. Por exemplo, com as configurações padrão do terminal, os \n
caracteres são convertidos \r\n
e 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 ssh
stdout 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