En
ssh host tail -f file
El ssh
cliente se conecta al sshd
servidor a host
través de una conexión TCP. sshd
se ejecuta tail -f
con su stdout redirigido a una tubería. sshd
lee lo que viene del otro extremo de la tubería y lo encapsula en el protocolo sshd para enviarlo al ssh
cliente. (con rshd
, tail
stdout habría sido el socket directamente, pero sshd
agrega cifrado y es capaz de multiplexar varias secuencias (como para redirección de puerto / agente / X11 / túnel, stderr) en una sola conexión TCP, por lo que tiene que recurrir a tuberías).
Cuando presiona CTRL-C, se envía un SIGINT al ssh
cliente. Eso hace ssh
que muera. Al morir, la conexión TCP se cierra. Y por lo tanto, en host
, sshd
muere también. tail
no se mata, pero su stdout ahora es una tubería sin lector en el otro extremo. Entonces, la próxima vez que escriba algo en su stdout, recibirá un SIGPIPE y morirá.
En:
ssh -t host 'tail -f file'
Es lo mismo, excepto que en lugar de estar con una tubería, la comunicación entre sshd
y tail
es a través de un pseudo-terminal. tail
El stdout es un pseudo-terminal esclavo (como /dev/pts/12
) y cualquier tail
escritura que haya read
en el lado maestro (posiblemente modificada por la disciplina de línea tty) sshd
y enviada encapsulada al ssh
cliente.
En el lado del cliente, con -t
, ssh
pone el terminal en raw
modo. En particular, eso desactiva el modo canónico del terminal y el manejo de la señal del terminal.
Entonces, cuando presiona Ctrl+C, en lugar de que la disciplina de la línea de terminal del cliente envíe un SIGINT al ssh
trabajo, simplemente envía el ^C
carácter a través de la conexión sshd
y lo sshd
escribe ^C
en el lado maestro del terminal remoto. Y la disciplina de línea del terminal remoto envía un SIGINT
a tail
. tail
luego muere, sshd
sale y cierra la conexión y ssh
finaliza (si no está ocupado con reenvíos de puertos u otros).
Además, con -t
, si el ssh
cliente muere (por ejemplo, si ingresa ~.
), la conexión se cierra y sshd
muere. Como resultado, se enviará un SIGHUP a tail
.
Ahora, tenga en cuenta que el uso -t
tiene efectos secundarios. Por ejemplo, con la configuración predeterminada del terminal, los \n
caracteres se convierten \r\n
y pueden suceder más cosas dependiendo del sistema remoto, por lo que es posible que desee emitir un stty -opost
(para deshabilitar el procesamiento posterior de la salida) en el host remoto si esa salida no está destinada a una 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
Otro inconveniente de usar -t
/ -tt
es que stdout y stderr no están diferenciados en el cliente. Tanto el stdout como el stderr del comando remoto se escribirán en el ssh
stdout del 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