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
-t
, se ossh
cliente morrer (por exemplo, se você entrar~.
)" O que é mesmo~.
?~.
é a sequência de escape que você digita para desconectar o cliente. Vejaman ssh
para detalhes.Você precisa de alocação de terminal no lado remoto:
ou mesmo
fonte
-t
ou-tt
funciona. Mas ainda não consigo entender o motivo real disso: digamos, quando eu chamo shell remotamente e fecho a conexão, o shell é encerrado. Mastail -f
não é. É claro que eu já li sobre a-t
opçãoman ssh
, mas não ajudou muito. Parece que eu não entendo alguns genéricos e ficaria feliz se você sugerir alguns documentos para ler sobre isso ou provavelmente explicar você mesmo. Obrigado!sshd
enviará aSIGHUP
. Mas onde nenhum terminal é, não pode haver desligamento conexão do terminal ...SIGHUP
e outros sinais, ainda sei quase nada sobre isso.tail -f
, então eu abrihtop
e envieiSIGHUP
a ele (pressionandoF9
->1
->Enter
) etail -f
é encerrado! Assim, a razão deve ser algum diferente ..tail
não reagiriaSIGHUP
. O problema é queSIGHUP
** não é enviado `paratail
sem um pseudo terminal. Você pode ver isso anexandostrace
atail
ambos os casos.