scp e compress allo stesso tempo, nessun salvataggio intermedio


64

Qual è il modo canonico di:

  • scp un file in una posizione remota
  • comprimere il file in transito ( taroppure no, file singolo o intera cartella 7zao qualcos'altro ancora più efficiente)
  • fare quanto sopra senza salvare i file intermedi

Conosco i tubi shell in questo modo:

tar cf - MyBackups | 7za a -si -mx=9 -ms=on MyBackups.tar.7z

essenzialmente:

  • rotolare un'intera cartella in una singola tar
  • passare i dati stdoutal stdinprogramma di compressione
  • applicare una compressione aggressiva

Qual è il modo migliore per farlo su un sshcollegamento, con l'atterraggio del file sul filesystem remoto?


Preferisco non sshfsmontare.


Questo non funziona:

scp <(tar cvf - MyBackups | 7za a -si -mx=9 -so) localhost:/tmp/tmp.tar.7z

perché:

/dev/fd/63: not a regular file

Risposte:


103

Esistono molti modi per fare ciò che vuoi. Il più semplice è usare un pìpe:

tar zcvf -  MyBackups | ssh user@server "cat > /path/to/backup/foo.tgz"

Qui, la compressione viene gestita da tarquali chiamate gzip( zflag). Puoi anche usare compress( Z) e bzip( j). Per 7z, fare questo:

tar cf - MyBackups | 7za a -si -mx=9 -ms=on MyBackups.tar.7z | 
   ssh user@server "cat > /path/to/backup/foo.7z"

Il modo migliore , tuttavia, è probabilmente rsync.

   Rsync is a fast and extraordinarily versatile  file  copying  tool.   It  can  copy
   locally, to/from another host over any remote shell, or to/from a remote rsync dae‐
   mon.  It offers a large number of options that control every aspect of its behavior
   and  permit  very  flexible  specification of the set of files to be copied.  It is
   famous for its delta-transfer algorithm, which reduces the amount of data sent over
   the network by sending only the differences between the source files and the exist‐
   ing files in the destination.  Rsync is widely used for backups and  mirroring  and
   as an improved copy command for everyday use.

rsyncha modo troppe opzioni. Vale davvero la pena leggerli, ma sono spaventosi a prima vista. Quelli a cui tieni in questo contesto sono:

    -z, --compress              compress file data during the transfer
        --compress-level=NUM    explicitly set compression level

   -z, --compress
          With this option, rsync compresses the file data as it is sent to the desti‐
          nation machine, which reduces the amount of data being transmitted --  
          something that is useful over a slow connection.

          Note  that this option typically achieves better compression ratios than can
          be achieved by using a compressing remote shell or a  compressing  transport
          because  it takes advantage of the implicit information in the matching data
          blocks that are not explicitly sent over the connection.

Quindi, nel tuo caso, vorresti qualcosa del genere:

rsync -z MyBackups user@server:/path/to/backup/

I file verrebbero compressi durante il trasporto e arriverebbero decompressi a destinazione.


Qualche altra scelta:

  • scp stesso può comprimere i dati

     -C      Compression enable.  Passes the -C flag to ssh(1) to
             enable compression.
    
    $ scp -C source user@server:/path/to/backup
    
  • Potrebbe esserci un modo per ottenere rsynce 7zagiocare bene, ma non ha senso farlo. Il vantaggio rsyncè che copierà solo i bit che sono stati modificati tra i file locali e remoti. Tuttavia, una piccola modifica locale può comportare un file compresso molto diverso, quindi non ha senso utilizzarlo rsyncper questo. Ciò complica le cose senza alcun beneficio. Usa direttamente sshcome mostrato sopra. Se vuoi davvero farlo, puoi provare dando una subshell come argomento a rsync. Sul mio sistema, non sono riuscito a farlo funzionare 7zaperché non ti consente di scrivere dati compressi su un terminale. Forse la tua implementazione è diversa. Prova qualcosa del genere ( questo non funziona per me ):

    rsync $(tar cf - MyBackups | 7za a -an -txz -si -so) \
      user@server:/path/to/backup
    
  • Un altro punto è che 7z non dovrebbe essere usato per i backup su Linux . Come indicato nella 7zpagina man:

    NON UTILIZZARE il formato 7-zip a scopo di backup su Linux / Unix perché:
    - 7-zip non memorizza il proprietario / gruppo del file.


3
Una buona nota da aggiungere è che a meno che non si stia trasferendo su una rete generalmente lenta, diciamo Internet, è meglio evitare la compressione poiché rallenta semplicemente la velocità di trasferimento. Su una LAN, -zè almeno il doppio più lento. Per una velocità ancora maggiore rispetto a rsyncing su ssh, imposta un demone rsync e rsync usando -Wflag (copia i file interi (senza algoritmo delta-xfer).
laebshade

2
Grazie! Accetterò questa grande risposta, ma per favore, aggiungo una riga di comando completa e autonoma che utilizza entrambi rsync e 7za , con output finale al filesystem remoto. Mi è piaciuto, -zma vorrei disaccoppiare lo stadio di compressione, quindi ... come userei rsyncin quel caso, per favore?
Robottinosino,

2
@Robottinosino vedi risposta aggiornata. Non ha senso usare rsynccon 7z. Si dovrebbe lavorare con rsync e un subshel come indicato ma non ho potuto capire come comunque.
terdon

4
+1 per scp -C. Sul disco remoto non c'era spazio sufficiente per contenere il file compresso, quindi non ho potuto comprimerlo prima del trasferimento. Una piccola opzione da riga di comando ha risolto il problema.
user37931

1
@knutole è sufficiente prima comprimere il file, quindi sincronizzarlo nuovamente. Fai una nuova domanda se hai bisogno di maggiori dettagli.
terdon

13

Penso che questo comando farà il trucco

ssh user@host "cd /path/to/data/;tar zc directory_name" | tar zx 

EDIT: una versione precedente era con due opzioni "f" sbagliate.

Ora, prima di tutto devi eseguire questo comando dall'host di destinazione. E dettagli da spiegare:

  1. ssh user @ host aprirà la connessione al computer host, da dove i dati devono essere trasferiti.
  2. cd / path / to / data porterà alla directory in cui sono memorizzati i dati richiesti
  3. tar zc * avvierà la compressione e la metterà nello STDOUT
  4. Ora pipe (|) eseguirà il pipeline dello STDOUT della sorgente sullo STDIN della destinazione in cui è in esecuzione "tar zx" e il flusso di dati di decompressione continua proveniente dalla sorgente.

Come puoi vedere, questo comando comprime al volo e risparmia larghezza di banda. Puoi utilizzare anche altre compressioni per risultati migliori, ma ricorda, la compressione e la decompressione richiedono cicli CPU.

Riferimento


tar: la vecchia opzione 'f' richiede un argomento.
Dimitri Kopriwa,

7

Piccolo miglioramento per la risposta di dkbhadeshiya : non devi fare cd dir, specifica tarinvece la directory di lavoro nel :

ssh user@host "tar -C /path/to/data/ -zc directory_name" | tar zx 

Puoi anche caricare la directory nello stesso modo:

tar zc directory_name/ | ssh user@host "tar zx -C /new/path/to/data/"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.