scp и сжимать одновременно, без промежуточного сохранения

64

Что такое канонический способ:

  • scp файл в удаленном месте
  • сжатие файла в пути ( tarили нет, отдельный файл или целая папка, 7zaили что-то еще, даже более эффективное)
  • сделать выше, не сохраняя промежуточные файлы

Я знаком с трубами оболочки как это:

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

по существу:

  • сворачивая всю папку в одну tar
  • передать данные stdoutв stdinпрограмму сжатия
  • применять агрессивное сжатие

Какой лучший способ сделать это по sshссылке, с посадкой файлов в удаленной файловой системе?


Я предпочитаю не sshfsмонтировать.


Это не работает:

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

потому что:

/dev/fd/63: not a regular file
Robottinosino
источник

Ответы:

103

Есть много способов сделать то, что вы хотите. Самое простое - использовать pìpe:

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

Здесь сжатие обрабатывается тем, tarкакие вызовы gzip( zфлаг). Вы также можете использовать compress( Z) и bzip( j). Для 7zэтого:

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

Лучший способ, однако, вероятно 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.

rsyncесть способ слишком много вариантов. Их действительно стоит прочитать, но они пугают с первого взгляда. Тем не менее, в этом контексте вам важны:

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

Итак, в вашем случае вы хотели бы что-то вроде этого:

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

Файлы будут сжаты во время транспортировки и распакованы в место назначения.


Еще несколько вариантов:

  • scp сам может сжать данные

     -C      Compression enable.  Passes the -C flag to ssh(1) to
             enable compression.
    
    $ scp -C source user@server:/path/to/backup
    
  • Может быть, есть способ получить rsyncи 7zaиграть хорошо, но в этом нет никакого смысла. Преимущество rsyncзаключается в том, что он будет копировать только те биты, которые изменились между локальным и удаленным файлами. Однако небольшое локальное изменение может привести к совершенно другому сжатому файлу, поэтому нет смысла использовать его rsyncдля этого. Это только усложняет ситуацию без пользы. Просто используйте прямой, sshкак показано выше. Если вы действительно хотите это сделать, попробуйте указать в качестве аргумента подоболочку rsync. В моей системе я не мог заставить это работать, 7zaпотому что это не позволяет вам записывать сжатые данные в терминал. Возможно, ваша реализация отличается. Попробуйте что-то вроде ( это не работает для меня ):

    rsync $(tar cf - MyBackups | 7za a -an -txz -si -so) \
      user@server:/path/to/backup
    
  • Другое дело, что 7z не следует использовать для резервного копирования в Linux . Как указано на 7zстранице руководства :

    НЕ ИСПОЛЬЗУЙТЕ формат 7-zip для резервного копирования в Linux / Unix, потому что:
    - 7-zip не хранит владельца / группу файла.

Тердон
источник
3
Следует добавить, что если вы не передаете по вообще медленной сети, скажем, через Интернет, лучше избегать сжатия, поскольку это просто замедляет скорость передачи. В локальной сети -zэто как минимум вдвое медленнее. Для еще большей скорости, чем rsyncing через ssh, установите демон rsync и rsync, используя -Wфлаг (копирует файлы целиком (без алгоритма delta-xfer).
laebshade
2
Спасибо! Я собираюсь принять этот замечательный ответ, но, пожалуйста, добавьте полную, автономную командную строку, которая использует оба, rsync и 7za , с окончательным выводом на удаленную файловую систему. Мне понравилось, -zно я бы хотел отделить стадию сжатия, так что ... как бы я использовал rsyncв этом случае, пожалуйста?
Robottinosino
2
@Robottinosino см. Обновленный ответ. Нет смысла использовать rsyncс 7z. Он должен работать с rsync и subhel, как показано, но я все равно не могу понять, как это сделать.
Terdon
4
+1 за scp -C. На удаленном диске не хватало места для хранения сжатого файла, поэтому я не смог сжать перед передачей. Одна маленькая опция командной строки заставила мою проблему уйти.
user37931
1
@knutole сначала просто заархивируйте файл, а затем rsync. Пожалуйста, задайте новый вопрос, если вам нужно больше деталей.
Тердон
13

Я думаю, что эта команда добьется цели

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

РЕДАКТИРОВАТЬ: более ранняя версия была с двумя неправильными опциями "f".

Теперь, прежде всего, вы должны выполнить эту команду с целевого хоста. И детали, которые будут объяснены:

  1. ssh user @ host откроет соединение с хост-машиной, откуда данные должны быть переданы.
  2. cd / path / to / data перейдет в каталог, где хранятся необходимые данные
  3. tar zc * запустит сжатие и поместит его в STDOUT
  4. Теперь pipe (|) будет направлять STDOUT источника к STDIN пункта назначения, где работает tar zx, и непрерывно распаковывает поток данных, поступающий из источника.

Как видите, эта команда сжимает на лету и сохраняет пропускную способность. Вы можете использовать и другие сжатия для получения лучших результатов, но помните, что сжатие и распаковка требуют циклов ЦП.

Ссылка

dkbhadeshiya
источник
tar: старая опция 'f' требует аргумента.
Дмитрий Коприва
7

Небольшое улучшение для ответа dkbhadeshiya : вам не нужно ничего делать cd dir, просто укажите tarвместо него рабочий каталог :

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

Вы также можете загрузить каталог таким же образом:

tar zc directory_name/ | ssh user@host "tar zx -C /new/path/to/data/"
tsionyx
источник