Pregunta

Creé un programa que itera sobre un montón de archivos e invoca algunos de ellos:

scp <file> user@host:<remotefile>

Sin embargo, en mi caso, puede haber miles de archivos pequeños que deban transferirse, y scp está abriendo una nueva conexión ssh para cada uno de ellos, lo que tiene bastante sobrecarga.

Me preguntaba si no existe una solución en la que mantenga en ejecución un proceso que mantenga la conexión y pueda enviarle "solicitudes" para copiar archivos individuales.

Idealmente, estoy buscando una combinación de algún programa emisor y receptor, de modo que pueda iniciar un solo proceso (1) al principio:

ssh user@host receiverprogram

Y para cada archivo, invoco un comando (2):

senderprogram <file> <remotefile>

y canalizar la salida de (2) a la entrada de (1), y esto provocaría que el archivo se transfiriera.Al final, puedo enviar al proceso (1) alguna señal para que finalice.

Preferiblemente los programas emisores y receptores son programas C de código abierto para Unix.Pueden comunicarse mediante un enchufe en lugar de un tubo, o cualquier otra solución creativa.

Sin embargo, es un restricción importante que cada archivo se transfiere en el momento en que lo repito:No es aceptable recopilar una lista de archivos y luego invocar una instancia de scp para transferir todos los archivos a la vez al final.Además, solo tengo acceso de shell simple al host receptor.

Actualizar: Encontré una solución para el problema de la sobrecarga de conexión utilizando las funciones de multiplexación de ssh; consulte mi propia respuesta a continuación.Sin embargo, estoy iniciando una recompensa porque tengo curiosidad por saber si existe un programa emisor/receptor como el que describo aquí.Parece que debería existir algo que pueda usarse, p.xmodem/ymodem/zmodem?

¿Fue útil?

Solución

De esta manera podría funcionar, y para otras cosas, este enfoque general es más o menos bien.

(
iterate over file list
  for each matching file
   echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud

Otros consejos

he encontrado una solución desde otro ángulo. Desde la versión 3.9 , soportes OpenSSH sesión de multiplexación : una única conexión puede llevar a varias sesiones de inicio de sesión o de transferencia de archivos. Esto evita el costo de puesta a punto por conexión.

En el caso de la pregunta, puede primero abrir una conexión con conjuntos de hasta un master control (-M) con un zócalo (-S) en una ubicación específica. No necesito una sesión (-N).

ssh user@host -M -S /tmp/%r@%h:%p -N

A continuación, puede invocar scp para cada archivo y dar instrucciones para utilizar el mismo socket:

scp -o 'ControlPath /tmp/%r@%h:%p' <file> user@host:<remotefile>

Este comando comienza a copiar casi instantáneamente!

También puede utilizar la toma de control de las conexiones ssh normales, que luego abrir de inmediato:

ssh user@host -S /tmp/%r@%h:%p

Si la toma de control ya no está disponible (por ejemplo, porque mataste al maestro), esta cae de nuevo a una conexión normal. Más información está disponible en este artículo .

Puede que funcione para usar SFTP en lugar de SCP, y para colocarlo en modo batch. Hacer archivo el comando batch una tubería o socket UNIX y piensos a los comandos, tal como desee los ejecutaron.

Seguridad sobre esto podría ser un poco difícil al final del cliente.

Has probado sshfs?Tú podrías:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

Dónde

  • /remote_dir era el directorio al que desea enviar archivos en el sistema al que está ingresando
  • /mnt/local_dir era la ubicación de montaje local

Con esta configuración puedes simplemente cp un archivo en el local_dir y sería enviado sftp a remote_host en su remote_dir

Tenga en cuenta que hay una única conexión, por lo que hay pocos gastos generales.

Es posible que necesites usar la bandera. -o ServerAliveInterval=15 para mantener un conexión indefinida

Necesitarás tener fuse instalado localmente y un servidor SSH compatible (y configurado para) sftp

puede ser que busca la siguiente: ZSSH

  

zssh (Zmodem SSH) es un programa para la transferencia de archivos de forma interactiva a una máquina remota, mientras que usando el shell seguro (SSH). Se pretende que sea una alternativa conveniente a SCP, lo que permite transferir archivos sin tener que abrir otra sesión y volver a autenticarse a sí mismo.

Usar rsync sobre ssh si se puede recoger todos los archivos a enviar en un solo directorio (o jerarquía de directorios).

Si usted no tiene todos los archivos en un solo lugar, por favor, dar algunas informaciones más sobre lo que quiere lograr y por qué no se puede empaquetar todos los archivos en un archivo y enviarla a través de. ¿Por qué es tan vital que cada archivo se envía inmediatamente? ¿Estaría bien si el archivo fue enviado con un pequeño retraso (como cuando 4K valor de los datos se ha acumulado)?

Es un pequeño y bonito problema.No conozco una solución empaquetada, pero se pueden hacer muchas cosas con scripts de shell simples.Probaría esto en el receptor:

#!/bin/ksh
# this is receiverprogram

while true
do
  typeset -i length
  read filename  # read filename sent by sender below
  read size      # read size of file sent
  read -N $size contents  # read all the bytes of the file
  print -n "$contents" > "$filename"
done

En el lado del remitente, crearía una canalización con nombre y leería desde la canalización, por ejemplo,

mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection

Luego, para enviar un archivo, probaría este script.

#!/bin/ksh
# this is senderprogram

FIFO=$HOME/my-connection

localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO

Si el tamaño del archivo es grande, probablemente no desee leerlo de una sola vez, por lo que algo del orden de

BUFSIZ=8192

rm -f "$filename"
while ((size >= BUFSIZ)); do
  read -N $BUFSIZE buffer
  print -n "$buffer" >> "$filename"
  size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"

Eventualmente querrás extender el script para poder pasar chmod y chgrp comandos.Dado que confía en el código de envío, probablemente sea más fácil estructurarlo para que el receptor simplemente llame al shell eval en cada línea, luego envía cosas como

print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO

y luego definir una función local read_and_copy_bytes.Obtener la cotización correcta es una tarea difícil, pero por lo demás debería ser sencillo.

¡Por supuesto, nada de esto ha sido probado!Pero espero que te dé algunas ideas útiles.

Parece un trabajo para el alquitrán? Tubería de su salida a SSH, y por el otro lado del tubo de la salida de nuevo a ssh alquitrán.

Creo que el escritorio GNOME usa una sola conexión SSH al acceder a un recurso compartido a través de SFTP (SSH). Supongo que esto es lo que está pasando porque veo un solo proceso de SSH cuando accedo a un recurso compartido remoto de esta manera. Así que si esto es cierto que debe ser capaz de utilizar el mismo programa para este fin.

La nueva versión de GNOME utiliza GVFS través GIO con el fin de realizar todas tipo de E / S a través de diferentes sistemas de apoyo. El paquete de Ubuntu gvfs-bin proporciona varias utilidades de línea de comandos que permiten manipular los backends desde la línea de comandos.

En primer lugar, tendrá que montar su carpeta de SSH:

SFTP

gvfs de montaje: // usuario @ host /

Y a continuación, puede utilizar la gvfs-copia para copiar los archivos. Creo que todas las transferencias de archivos se llevarán a cabo a través de un único proceso de SSH. Incluso puede utilizar ps para ver qué proceso está siendo utilizado.

Si se siente más aventurero puede incluso escribir su propio programa en C o en algún otro lenguaje de alto nivel que proporciona una API para GIO.

Una de las opciones es concha es una aplicación cliente y el servidor SSH escrito en Python usando el < a href = "http://twistedmatrix.com/trac/" rel = "nofollow noreferrer"> marco Twsited . Usted puede usarlo para escribir una herramienta que acepta solicitudes a través de algún otro protocolo (HTTP o de dominio Unix sockets, FTP, SSH o lo que sea) y desencadena la transferencia de archivos a través de una conexión SSH larga ejecución. De hecho, tengo varios programas de producción que utilizan esta técnica para evitar múltiples configuraciones de conexión SSH.

pregunta aquí hace un par de semanas. La respuesta aceptado propuesto para abrir un túnel cuando ssh'ing a la máquina remota y utilizar ese túnel para las transferencias de CPS.

tal vez CurlFTPFS podría ser una solución válida para usted.

Parece que simplemente monta la carpeta de una computadora externa en su computadora a través de SFTP.Una vez hecho esto, debería poder utilizar su habitual cp comandos y todo se hará de forma segura.

Desafortunadamente no pude probarlo yo mismo, ¡pero avíseme si funciona para usted!

Edición 1: He podido descargarlo y probarlo.Como temía, requiere que el cliente tenga un servidor FTP. Sin embargo, He encontrado otro programa que tiene exactamente el mismo concepto que el que estás buscando. sshfs le permite conectarse a su computadora cliente sin necesidad de ningún servidor especial.Una vez que haya montado una de sus carpetas, podrá utilizar su carpeta normal. cp comandos para mover los archivos que necesite a más.Una vez que haya terminado, debería ser cuestión de sonreír. umount /path/to/mounted/folder.¡Déjame saber cómo funciona esto!

rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder

Esto utilizará SSH para transferir archivos, de forma no lenta.

Debe ser sencillo, escribir un pequeño guión envoltorio que hace algo como esto.

  1. tar los archivos
  2. enviar el archivo tar-
  3. untar en el otro lado

Algo como esto:

  1. alquitrán -cvzf archivos test.tgz ....
  2. SCP test.tgz user@other.site.com:.
  3. ssh user@other.site.com alquitrán -xzvf test.tgz

/ Johan

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top