scp und compress gleichzeitig, kein Zwischenspeichern


64

Was ist der kanonische Weg zu:

  • scp eine Datei an einen entfernten Ort
  • Komprimieren Sie die Datei während der Übertragung ( taroder nicht, einzelne Datei oder ganzen Ordner 7zaoder etwas noch effizienteres)
  • Führen Sie die obigen Schritte aus, ohne Zwischendateien zu speichern

Ich kenne mich mit Hüllrohren wie diesen aus:

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

im Wesentlichen:

  • Rollen Sie einen ganzen Ordner in einen einzigen tar
  • Daten stdoutan stdindas Komprimierungsprogramm weiterleiten
  • aggressive Kompression anwenden

Was ist der beste Weg, dies über einen sshLink zu tun , wobei die Datei auf dem entfernten Dateisystem landet?


Ich ziehe es vor, nicht zu sshfsbesteigen.


Das funktioniert nicht:

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

da:

/dev/fd/63: not a regular file

Antworten:


103

Es gibt viele Möglichkeiten, um das zu tun, was Sie wollen. Am einfachsten ist die Verwendung eines Pìpes:

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

Hier wird die Komprimierung von tarwelchen Aufrufen gzip( zFlag) behandelt. Sie können auch compress( Z) und bzip( j) verwenden. Für 7z, dies zu tun:

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

Der beste Weg ist jedoch wahrscheinlich 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.

rsynchat viel zu viele optionen. Es lohnt sich wirklich, sie durchzulesen, aber sie sind auf den ersten Blick beängstigend. Diejenigen, die Sie in diesem Zusammenhang interessieren, sind jedoch:

    -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.

In Ihrem Fall möchten Sie also Folgendes:

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

Die Dateien werden während des Transports komprimiert und kommen dekomprimiert am Ziel an.


Einige weitere Möglichkeiten:

  • scp selbst kann die Daten komprimieren

     -C      Compression enable.  Passes the -C flag to ssh(1) to
             enable compression.
    
    $ scp -C source user@server:/path/to/backup
    
  • Es mag eine Möglichkeit geben, nett zu werden rsyncund 7zazu spielen, aber es macht keinen Sinn, dies zu tun. Der Vorteil rsyncist, dass nur die Bits kopiert werden, die sich zwischen der lokalen und der entfernten Datei geändert haben. Eine kleine lokale Änderung kann jedoch zu einer sehr unterschiedlichen komprimierten Datei führen, sodass es keinen Sinn macht, rsyncdiese zu verwenden. Es macht die Sache nur komplizierter und bringt keinen Nutzen. Verwenden Sie einfach direkt sshwie oben gezeigt. Wenn Sie dies wirklich tun möchten, können Sie versuchen, indem Sie eine Subshell als Argument angeben rsync. Auf meinem System konnte ich dies nicht zum Laufen bringen, 7zada Sie damit keine komprimierten Daten auf ein Terminal schreiben können. Vielleicht ist Ihre Implementierung anders. Versuchen Sie etwas wie ( das funktioniert bei mir nicht ):

    rsync $(tar cf - MyBackups | 7za a -an -txz -si -so) \
      user@server:/path/to/backup
    
  • Ein weiterer Punkt ist, dass 7z für Backups unter Linux nicht verwendet werden sollte . Wie auf der 7zManpage angegeben:

    Verwenden Sie das 7-zip-Format NICHT für Sicherungszwecke unter Linux / Unix, weil:
    - 7-zip den Eigentümer / die Gruppe der Datei nicht speichert.


3
Wenn Sie nicht über ein im Allgemeinen langsames Netzwerk, z. B. das Internet, übertragen, sollten Sie eine Komprimierung vermeiden, da dies nur die Übertragungsrate verlangsamt. In einem LAN -zist es mindestens doppelt so langsam. Richten Sie einen rsync-Daemon und rsync mithilfe des -WFlags ein (kopiert Dateien als Ganzes (ohne Delta-Xfer-Algorithmus) , um eine noch schnellere Synchronisation als mit ssh zu erreichen .
laebshade

2
Vielen Dank! Ich werde diese großartige Antwort akzeptieren, aber bitte fügen Sie eine vollständige, eigenständige Befehlszeile hinzu, die beide rsync und 7za mit der endgültigen Ausgabe an das Remote-Dateisystem verwendet. Ich mochte, -zaber ich möchte die Komprimierungsstufe so entkoppeln. Wie würde ich rsyncin diesem Fall bitte verwenden?
Robottinosino

2
@Robottinosino siehe aktualisierte Antwort. Es hat keinen Sinn, rsyncmit zu verwenden 7z. Es sollte wie gezeigt mit rsync und einer Subshel ​​funktionieren, aber ich konnte es trotzdem nicht herausfinden.
terdon

4
+1 für scp -C. Auf der Remote-Festplatte war nicht genügend Speicherplatz für die komprimierte Datei vorhanden, sodass ich sie vor der Übertragung nicht komprimieren konnte. Eine kleine Befehlszeilenoption ließ mein Problem verschwinden.
user37931

1
@knutole komprimiere die Datei zuerst und synchronisiere sie dann. Bitte stellen Sie eine neue Frage, wenn Sie weitere Informationen benötigen.
Terdon

13

Ich denke, dieser Befehl wird den Trick machen

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

BEARBEITEN: Eine frühere Version hatte zwei falsche "f" -Optionen.

Jetzt müssen Sie zuerst diesen Befehl vom Zielhost ausführen. Und noch zu erklärende Details:

  1. ssh user @ host öffnet die Verbindung zum Hostrechner, von dem die Daten übertragen werden sollen.
  2. cd / path / to / data wechselt in das Verzeichnis, in dem die erforderlichen Daten gespeichert sind
  3. tar zc * startet die Komprimierung und legt sie auf dem STDOUT ab
  4. Jetzt leitet pipe (|) das STDOUT der Quelle an das STDIN des Ziels weiter, auf dem "tar zx" ausgeführt wird, und dekomprimiert kontinuierlich den Datenstrom von der Quelle.

Wie Sie sehen, komprimiert dieser Befehl im laufenden Betrieb und spart Bandbreite. Sie können auch andere Komprimierungen verwenden, um bessere Ergebnisse zu erzielen. Beachten Sie jedoch, dass für Komprimierung und Dekomprimierung CPU-Zyklen erforderlich sind.

Referenz


tar: Alte Option 'f' erfordert ein Argument.
Dimitri Kopriwa

7

Kleine Verbesserung für die Antwort von dkbhadeshiya : Sie müssen nicht tun cd dir, tarsondern geben stattdessen das Arbeitsverzeichnis an :

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

Sie können das Verzeichnis auch auf die gleiche Weise hochladen:

tar zc directory_name/ | ssh user@host "tar zx -C /new/path/to/data/"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.