La asignación de terminal rompe archivos mientras se usa ssh para la transferencia

La asignación de terminal rompe archivos mientras se usa ssh para la transferencia

Solía ssh​​descomprimir un archivo remoto usando:

ssh host "cat file.tgz" | tar xf -

Esto funciona perfectamente bien. Sin embargo, mientras jugaba con comandos forzados, noté que pty-allocation cambia la salida del comando:

ssh host -T "cat file.tgz" >first_file
ssh host -t "cat file.tgz" >second_file

Aquí el primer archivo está bien, pero el segundo archivo está roto.

¿Por qué exactamente la asignación de un pty cambia la salida?

Respuesta1

Ayuda a leer elsshpágina del manual:

 -T      Disable pseudo-tty allocation.                                     

 -t      Force pseudo-tty allocation.  This can be used to execute arbi‐    
         trary screen-based programs on a remote machine, which can be      
         very useful, e.g. when implementing menu services.  Multiple -t    
         options force tty allocation, even if ssh has no local tty.

Cuando lo dicesasignarapseudo-tty, cualquier proceso en el lado remoto puede ver que la conexión es una terminal "real" y enviará mensajes adicionales ya que la conexión es interactiva. En la inicialización de su shell, también puede configurar los modos de terminal, que puede inspeccionar usando stty -a. Los modos terminales se utilizan paratraducirentre su entrada de teclado y el host, y entre el texto enviado desde el host a su terminal:

  • SinAl inicializar, la conexión no es una terminal y no se realiza ninguna traducción.
  • ConAl inicializar, la terminal traducirá una nueva línea ( \n) a retorno de carro y avance de línea (0x0d, 0x0a). También (para la mayoría de los usuarios) traducirá pestañas a espacios.

El efecto descrito es paratraducción. Sin eso, tuinteractivoLa sesión "escalera" a través de la pantalla y queda inutilizable.

Su shell también puede imprimir información adicional, pero para un solo comando, elsugerenciapor @kba es engañoso porque el shell normalmente no envíaindicaciones, y los controles ssh como los ~Cmencionados se aplican aaporteen vez deproducción.

Cuando se ejecuta en una terminal, ssh también imprimirá un mensaje al cerrar la conexión. Pero eso está escrito en el error estándar.

Respuesta2

¿Por qué exactamente la asignación de un pty cambia la salida?

Porque el lado remoto (con terminal asignado) "inyectará" caracteres de control para su terminal local (Básicamente códigos de control C0 y C1.). Y dado que su lado local no es una terminal, sino un archivo, simplemente los vuelca en ese archivo.

SSH intenta hacer lo mejor que puede para adivinar lo que desea (si la entrada estándar no es TTY, no asignará TTY remoto a menos que agregue -ttconmutadores). La opción existe por una razón y si desea una transferencia binaria, no desea que las terminales alteren su archivo.

Puede ver este comportamiento simplemente transfiriendo archivos pequeños y luego volcándolos en formato hexadecimal:

$ ssh -t host "cat test" > /tmp/test.t
$ ssh host "cat test" > /tmp/test
$ hexdump -C /tmp/test
00000000  0a 2a 20 46 72 69 20 46  65 62 20 31 32 20 32 30  |.* Fri Feb 12 20|
00000030  6d 3e 20 33 2e 34 2e 31  2d 31 0a 2d 20 4e 65 77  |m> 3.4.1-1.- New|

$ hexdump -C /tmp/test.t
00000000  0d 0a 2a 20 46 72 69 20  46 65 62 20 31 32 20 32  |..* Fri Feb 12 2|
00000030  6f 6d 3e 20 33 2e 34 2e  31 2d 31 0d 0a 2d 20 4e  |om> 3.4.1-1..- N|

Para mí, la diferencia está solo en los dos bytes 0d 0aantes de cada nueva línea, pero podría haber más (la línea de Linux Newline es solo \n, pero el terminal obtiene ambos \r\n).

información relacionada