
Cuando todo lo que tiene es una consola serie (por ejemplo, a través de telnet a través de un servidor terminal), ¿qué métodos se pueden utilizar para transferir archivos dentro/fuera de un host?
Cortar/pegar funciona para cosas pequeñas/imprimibles y he jugado con una combinación de uuencode/uudecode (con gzip) para manejar lo no imprimible, pero todo es muy limitante.
Respuesta1
Los programas de la consola serie¹ que usarás en el otro extremo de la conexión tendrán alguna forma de enviar un archivo al lado remoto. La forma exacta de hacerlo depende de los recursos que tenga disponibles en el sistema remoto.
Tengo lrzsz
o kermit
en el Lado Remoto
El caso más sencillo es si tiene un programa sólido de transferencia de archivos binarios instalado en el lado remoto, comolrzsz
okermit
. Esto alguna vez fue más común que hoy, pero es posible que su sistema particular todavía tenga uno de estos.
Es casi seguro que el programa de consola serie que estás usando en el lado local tenga una forma de realizar una carga Zmodem o Kermit, que te permite enviar lo que necesites directamente.
En el caso de Zmodem, simplemente escriba rz
en el sistema remoto, lo que envía una cadena especial que el terminal serial local debe entender, lo que hace que aparezca un cuadro de diálogo de selección de archivos.
Kermit es un protocolo más simple, por lo que en ese caso deberá iniciar la transferencia manualmente.
No tengo un programa de transferencia de archivos binarios, pero sí tengo uuencode
/base64
Existen varias ventajas al utilizar un programa de transferencia de archivos binarios adecuado como lrzsz
o kermit
: eficiencia, suma de verificación, reintentos automáticos, reanudación de transferencias abortadas, transferencia de archivos múltiples, etc., pero estas sonlujos. Si solo necesita enviar un archivo, o envía archivos raramente, puede realizar cargas ASCII.
Porqueprotocolos terminalesinterpretar muchos de los valores de bytes que ocurren en un archivo de datos binarios, no puede enviar el archivo directamente a través de la misma conexión; Si lo hace, el código de emulación de terminal en cualquiera de los extremos intentará interpretar algunos de los datos, corrompiéndolos y probablementeconfusoel código de manejo del terminal también.
Esto se soluciona codificando los datos binarios en un subconjunto seguro de ASCII en el lado local y luego convirtiéndolos nuevamente en datos binarios sin procesar en el lado remoto. Esto es lo que eluuencode
ybase64
los programas lo hacen, diferenciándose sólo en elecciones de algoritmos menores.
En el sistema local, codifica el archivo:²
$ uuencode -o sbf.uue some-binary-file.gz some-binary-file.gz
Luego escribe este comando en el sistema remoto y envía el archivo usando la función "carga ASCII" de la consola serie local:
$ cat | uudecode
Cuando finalice la carga del archivo, presione Ctrl-Cpara salir de cat
. Ahora tienes tu archivo decodificado en el sistema remoto, como querías.
Pero tengoMuchos¡Los archivos para enviar y la transcodificación ASCII imprimible son una molestia!
No es difícil alcanzar un nivel superior de tecnología. Si el sistema remoto tiene un compilador de C, puede utilizar la técnica anterior para enviar al sistema remoto una copia del lrzsz
código fuente. Del lado local:
$ uuencode -o lrzsz.tgz.uue lrzsz-0.12.20.tar.gz lrzsz-0.12.20.tar.gz
Luego, en el sistema remoto, escriba esto mediante el programa de la consola serie:
$ cat | uudecode
^C
$ tar xvf lrzsz-0.12.20.tar.gz
...build lrzsz normally
Después de iniciar el primer comando, realice una "carga ASCII" del lrzsz.tgz.uue
archivo al sistema remoto. La canalización acepta los datos codificados y los decodifica en un tarball binario, que puede descomprimir y compilar.
Pero no tengo un compilador de C en el sistema remoto
Si ni siquiera tiene un compilador en el sistema remoto, puedecompilación cruzadael rz
programa (o lo que sea) en el sistema local y envíelo al sistema remoto utilizando la técnica anterior.
Notas a pie de página:
Debe proporcionar el nombre del archivo de entrada a esta versión
uuencode
dos veces, una para nombrar la fuente de los datos de entrada y otra para declarar cómo el sistema remoto debe llamar al archivo cuando decodifica los datos en un archivo de salida. Es posible que desee que el sistema remoto tenga un nombre diferente para su archivo de salida.Su versión local de
uuencode
puede comportarse de manera diferente.
Respuesta2
Básicamente, debe utilizar métodos anteriores a Internet para realizar transferencias a través de un tty en serie y debe tener una forma de recibir la transferencia en el otro lado. Obviamente, la mejor manera de hacer esto es usando ZMODEM, lo que significa que necesitas tener una herramienta como la que sz
ya tienes en el lado receptor. Sin embargo, esto no siempre es posible, por ejemplo, cuando el destino receptor es un enrutador sin red.
La única forma posible de realizar esta transferencia es directamente a través del canal, utilizando ASCII seguro para terminal, en un estilo limpio anterior a 8 bits. Voy a utilizar herramientas más modernas, que espero estén instaladas en la mayoría de los sistemas.
Remitente:
Primero codificamos nuestro archivo.
base64 file.tar.gz > file.tar.gz.b64
Ahora asegúrese de que su comando com send-file sea, ascii-xfr
esta era mi línea de comando de conexión
picocom -f n -p n -d 8 -b 115200 --send-cmd "ascii-xfr -snv" /dev/ttyS0
Normalmente queremos ascii-xfr
en el lado receptor, pero como no lo tenemos, esto -n
soluciona este problema manteniendo los finales de línea correctos.
Receptor:
Ahora que nos hemos conectado, vaya al directorio donde desea recibir el archivo.
cd /tmp/
cat > file.tar.gz.b64
En picocom, soloCTRL+a+se ingrese la ruta completa del archivo que estoy enviando. Una vez que se complete la transferencia, deberásCTRL+cpara romper eso cat
.
Ahora decodificamos el archivo,
base64 -d file.tar.gz.b64 > file.tar.gz
Haga todo lo que pueda para verificar que el archivo sea IDÉNTICO al que envió, porque una transferencia ASCII no tiene protección de suma de verificación. Mi caja de recepción tenía sha512sum
, pero cualquier comando de suma de verificación sería suficiente. Una vez que confirmes manualmente la coincidencia de las sumas, ¡puedes asumir que la transferencia fue exitosa!
Respuesta3
No sé si esto funcionaría si todo lo que tuviera fuera una consola serie, pero si tiene acceso a la red, podría usarlo nc(1)
para copiar archivos usando TCP/IP.
# WARNING: Depending on your setup, this could make your system unbootable
[email protected] # nc -l 8675 | dd of=/dev/sdXXX
[email protected] # dd if=/dev/sdYYY | nc destination-box.local 8675
En el ejemplo anterior, cloné sdbYYY
desde un cuadro de origen al sdaXXX
cuadro de destino. Mi elección de 8675 como número de puerto TCP fue arbitraria; puedes usar cualquier puerto al que tengas acceso. Y no tiene por qué ser un dispositivo; puede ser cualquier archivo.
[email protected] $ nc -l 12345 >> ~/.ssh/authorized_keys
[email protected] $ cat ~/.ssh/id_rsa.pub | nc destination-box.local 12345
En el segundo ejemplo, copié mi clave pública rsa ( ~/.ssh/id_rsa.pub
) y la agregué al archivo de claves autorizadas para el host de destino.
Respuesta4
yo usaríakermit, el abuelo de los programas de transferencia de archivos. Ya lo usábamos mucho antes de que existiera Linux.