En
ssh host tail -f file
El sshcliente se conecta al sshdservidor a hosttravés de una conexión TCP. sshdse ejecuta tail -fcon su stdout redirigido a una tubería. sshdlee lo que viene del otro extremo de la tubería y lo encapsula en el protocolo sshd para enviarlo al sshcliente. (con rshd, tailstdout habría sido el socket directamente, pero sshdagrega 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 sshcliente. Eso hace sshque muera. Al morir, la conexión TCP se cierra. Y por lo tanto, en host, sshdmuere también. tailno 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 sshdy tailes a través de un pseudo-terminal. tailEl stdout es un pseudo-terminal esclavo (como /dev/pts/12) y cualquier tailescritura que haya readen el lado maestro (posiblemente modificada por la disciplina de línea tty) sshdy enviada encapsulada al sshcliente.
En el lado del cliente, con -t, sshpone el terminal en rawmodo. 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 sshtrabajo, simplemente envía el ^Ccarácter a través de la conexión sshdy lo sshdescribe ^Cen el lado maestro del terminal remoto. Y la disciplina de línea del terminal remoto envía un SIGINTa tail. tailluego muere, sshdsale y cierra la conexión y sshfinaliza (si no está ocupado con reenvíos de puertos u otros).
Además, con -t, si el sshcliente muere (por ejemplo, si ingresa ~.), la conexión se cierra y sshdmuere. Como resultado, se enviará un SIGHUP a tail.
Ahora, tenga en cuenta que el uso -ttiene efectos secundarios. Por ejemplo, con la configuración predeterminada del terminal, los \ncaracteres se convierten \r\ny 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/ -ttes 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 sshstdout 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
-t, si elsshcliente muere (por ejemplo, si ingresa~.)" ¿Qué es~.nuevamente?~.es la secuencia de escape que ingresas para desconectar al cliente. Verman sshpara más detalles.Necesita asignación de terminal en el lado remoto:
o incluso
fuente
-to-ttfunciona. Pero todavía no puedo entender la verdadera razón de esto: por ejemplo, cuando llamo a Shell de forma remota y cierro la conexión, Shell finaliza. Perotail -fno lo es. Por supuesto, ya he leído sobre la-topciónman ssh, pero no ayudó mucho. Parece que no entiendo algunos genéricos, y me alegraría si sugieres algunos documentos para leer sobre ellos, o probablemente te los expliques tú mismo. ¡Gracias!sshdenvía unSIGHUP. Pero donde no hay terminal, no puede haber una conexión de terminal ...SIGHUPy otras señales, todavía no sé casi nada al respecto.tail -f, luego lo abríhtopy lo enviéSIGHUP(presionandoF9->1->Enter), ¡ytail -fse terminó! Entonces, la razón debería ser diferente ...tailno reaccionaríaSIGHUP. El problema es queSIGHUP** no se envía`tailsin un pseudo terminal. Se puede ver que uniendostraceatailque en ambos casos.