Domanda

Ho creato un programma che itera su un gruppo di file e invoca per alcuni di loro:

scp <file> user@host:<remotefile>

Tuttavia, nel mio caso, ci possono essere migliaia di piccoli file che hanno bisogno di trasferire, e SCP sta aprendo una nuova connessione SSH per ciascuno di essi, che ha un po 'di spese generali.

Mi chiedevo se esiste una soluzione dove tengo un processo in esecuzione che mantiene il collegamento e posso inviarlo "richieste" per copiare singoli file.

Idealmente, sto cercando una combinazione di qualche programma mittente e destinatario, in modo tale che posso iniziare un singolo processo (1) all'inizio:

ssh user@host receiverprogram

E per ogni file, invoco un comando (2):

senderprogram <file> <remotefile>

e reindirizza l'output di (2) all'ingresso di (1), e ciò causerebbe il file da trasferire. Alla fine, posso solo inviare processo (1) un segnale per terminare.

programmi Preferibilmente il mittente e il destinatario sono programmi C open source per Unix. Che comunicano utilizzando una presa invece di un tubo, o qualsiasi altra soluzione creativa.

Tuttavia, si tratta di un importante vincolo che ogni file viene trasferito al momento mi scorrere su di esso: non è accettabile per raccogliere un elenco di file e quindi richiamare un'istanza di scp a trasferire tutti i file in una sola volta, alla fine. Inoltre, ho solo semplice accesso shell all'host ricevente.

Aggiornamento: ho trovato una soluzione per il problema della connessione in testa l'uso delle funzioni di multiplazione di SSH, vedere la mia risposta qui di seguito. Eppure, sto iniziando una taglia perché sono curioso di scoprire se esiste un programma mittente / destinatario come ho descritto qui. Sembra che ci dovrebbe esistere qualcosa che può essere utilizzato, ad esempio, xmodem / ymodem / Zmodem?

È stato utile?

Soluzione

In questo modo avrebbe funzionato, e per altre cose, questo approccio generale è più o meno a destra.

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

Altri suggerimenti

Ho trovato una soluzione da un'altra angolazione. Dalla versione 3,9 , supporti OpenSSH sessione multiplexing : una singola connessione può trasportare più sessioni d'accesso o il trasferimento di file. Questo evita il costo di set-up per ogni connessione.

Per il caso della domanda, posso aprire la connessione con stabilisce un master di controllo (-M) con una presa (-S) in una posizione specifica. Non ho bisogno di una sessione (-N).

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

Avanti, posso richiamare scp per ogni file e istruzioni al fine di utilizzare lo stesso socket:

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

Questo comando inizia a copiare quasi istantaneamente!

È inoltre possibile utilizzare la presa di controllo per le normali connessioni ssh, che sarà quindi aprire immediatamente:

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

Se la presa di controllo non è più disponibile (per esempio, perché avete ucciso il padrone), questo rientra di nuovo ad un normale connessione. Maggiori informazioni sono disponibili nella questo articolo .

Potrebbe funzionare per usare SFTP invece di SCP, e di mettere in modalità batch. Effettuare il file comando batch un tubo o socket di dominio UNIX e mangimi comandi ad esso come si desidera loro eseguiti.

Sicurezza su questo potrebbe essere un po 'difficile sul lato client.

Hai provato sshfs ? Si potrebbe:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

Dove

  • /remote_dir è la directory che si desidera inviare i file sul sistema che si sta sshing in
  • /mnt/local_dir è stata la posizione locale di montaggio

Con questa impostazione si può semplicemente cp un file nella local_dir e sarebbe inviato oltre sftp al remote_host nella sua remote_dir

Si noti che v'è una singola connessione, quindi c'è poco in termini di overhead

Potrebbe essere necessario utilizzare il flag -o ServerAliveInterval=15 di mantenere un collegamento indefinito

È necessario avere fuse installati a livello locale e un server SSH di supporto (e configurato per) <=>

Può essere che si sta cercando in questo modo: ZSSH

  

zssh (Zmodem SSH) è un programma per trasferire interattivamente file a un computer remoto mentre si utilizza la shell sicura (ssh). Esso è destinato a essere una comoda alternativa al SCP, che consente di trasferire i file senza dover aprire un'altra sessione e ri-autenticarsi se stessi.

Usa rsync su ssh se è possibile raccogliere tutti i file da inviare in una singola directory (o gerarchia di directory).

Se non si dispone di tutti i file in un unico luogo, si prega di fornire alcune informazioni su ciò che si vuole raggiungere e perché non potete imballare tutti i file in un archivio e inviare che oltre. Perché è così vitale che ogni file viene inviato immediatamente? Sarebbe bene se il file è stato inviato con un breve ritardo (come quando 4K vale la pena di dati ha accumulato)?

E 'un bel po' di problemi. Io non sono a conoscenza di una soluzione preconfezionata, ma si potrebbe fare molto con semplici script di shell. Mi piacerebbe provare questo al ricevitore:

#!/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

Al lato del mittente vorrei creare una named pipe e leggere dal tubo, per es.,

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

Poi, per inviare un file mi piacerebbe provare questo 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

Se la dimensione del file è di grandi dimensioni che probabilmente non si vuole leggere in una volta sola, quindi qualcosa dell'ordine di

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"

Alla fine si vorrà estendere lo script in modo da poter passare attraverso chmod e chgrp comandi. Dal momento che si considera attendibile il codice di invio, è probabilmente più facile da strutturare la cosa in modo che il ricevitore chiama semplicemente shell eval su ogni linea, quindi inviare roba come

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

e quindi definire una funzione locale read_and_copy_bytes. Ottenere la giusta citazione è un orso, ma per il resto dovrebbe essere semplice.

Naturalmente, niente di tutto questo è stato testato! Ma spero che ti dà alcune idee utili.

Sembra un lavoro per tar? Tubo sua uscita a SSH, e dall'altro lato tubo dell'uscita ssh ritorna tar.

Credo che il desktop GNOME utilizza una singola connessione SSH quando si accede a una condivisione tramite SFTP (SSH). Sto indovinando che questo è ciò che sta accadendo, perché vedo un unico processo SSH quando accedo una condivisione remota in questo modo. Quindi, se questo è vero si dovrebbe essere in grado di utilizzare lo stesso programma per questo scopo.

La nuova versione di GNOME utilizzata GVFS attraverso GIO al fine di eseguire tutti tipo di I / O tramite diversi backend. Il pacchetto di Ubuntu gvfs-bin fornisce varie utility a riga di comando che consentono di manipolare i backend dalla riga di comando.

In primo luogo è necessario montare la cartella SSH:

sftp

gvfs-mount: // utente @ host /

E quindi è possibile utilizzare il gvfs-copia per copiare i file. Credo che tutti i trasferimenti di file saranno eseguiti attraverso un unico processo di SSH. È anche possibile utilizzare ps per vedere quale processo viene utilizzato.

Se vi sentite più avventurosi si può anche scrivere il proprio programma in C o in qualche altro linguaggio di alto livello che fornisce un API per GIO.

Una possibilità è Conch è un'implementazione client e il server SSH scritto in Python utilizzando il < a href = "http://twistedmatrix.com/trac/" rel = "nofollow noreferrer"> quadro Twsited . Si potrebbe utilizzare per scrivere uno strumento che accetta le richieste tramite qualche altro protocollo (HTTP o di dominio Unix socket, FTP, SSH o altro) e fa scattare il trasferimento di file tramite una connessione SSH lunga esecuzione. Infatti, ho diversi programmi di produzione che utilizzano questa tecnica per evitare molteplici configurazioni di connessione SSH.

molto simile domanda qui un paio di settimane fa. La risposta accettata proposto di aprire un tunnel quando ssh'ing al computer remoto e di utilizzare tale tunnel per i trasferimenti SCP.

curlftpfs potrebbe essere una valida soluzione per voi.

Sembra che solo monta la cartella di un computer esterno al computer tramite SFTP. Una volta fatto, si dovrebbe essere in grado di utilizzare i normali comandi cp e tutto sarà fatto in modo sicuro.

Purtroppo non ero in grado di testare fuori io stesso, ma fatemi sapere se funziona per ya!

Modifica 1: sono stato in grado di scaricare e testarlo. Come temevo che richiede che il cliente dispone di un server FTP. Tuttavia , ho trovato un altro programma che fa ha esattamente lo stesso concetto come quello che si sta cercando. sshfs consente di collegare al computer client senza bisogno di alcun server speciale. Dopo aver montato una delle cartelle, è possibile utilizzare i comandi tuo umount /path/to/mounted/folder normale per spostare file eventualmente necessario di più. Una volta che hai finito, dovrebbe quindi essere una questione sorriso di <=>. Fammi sapere come questo funziona!

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

Questo userà SSH per trasferire i file, in modo non-slow

Keep it simple, scrivere un piccolo script wrapper che fa qualcosa di simile.

  1. tar i file
  2. inviare il tar-file
  3. untar sul lato opposto

Qualcosa di simile a questo:

  1. tar -cvzf file test.tgz ....
  2. SCP test.tgz user@other.site.com:.
  3. ssh user@other.site.com tar -xzvf test.tgz

/ Johan

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top