scp e comprimir ao mesmo tempo, não intermediário salvar

55

Qual é o caminho canônico para:

  • scp um arquivo para um local remoto
  • compactar o arquivo em trânsito ( tar ou não, arquivo único ou pasta inteira, 7za ou outra coisa ainda mais eficiente)
  • faça o acima sem salvar arquivos intermediários

Estou familiarizado com os canos do shell como este:

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

essencialmente:

  • rolando uma pasta inteira em um único tar
  • passar dados por meio de stdout para stdin do programa de compactação
  • aplica a compactação agressiva

Qual é a melhor maneira de fazer isso em um link ssh , com o arquivo sendo acessado no sistema de arquivos remoto?

Eu prefiro não sshfs mount.

Isso não funciona:

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

porque:

/dev/fd/63: not a regular file
    
por Robottinosino 30.03.2013 / 03:39

3 respostas

89

Existem várias maneiras de fazer o que você deseja. O mais simples é usar um pìpe:

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

Aqui, a compactação está sendo manipulada por tar , que chama gzip ( z flag). Você também pode usar compress ( Z ) e bzip ( j ). Para 7z , faça isso:

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

A melhor forma, no entanto, provavelmente é 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 tem caminho muitas opções. Realmente vale a pena ler através deles, mas eles são assustadores à primeira vista. Aqueles com quem você se importa nesse contexto são:

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

Então, no seu caso, você gostaria de algo assim:

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

Os arquivos serão compactados enquanto estiverem em trânsito e serão descomprimidos no destino.

Mais algumas escolhas:

  • scp pode compactar os dados

     -C      Compression enable.  Passes the -C flag to ssh(1) to
             enable compression.
    
    $ scp -C source user@server:/path/to/backup
    
  • Pode haver uma maneira de fazer com que rsync e 7za sejam bons, mas não faz sentido fazê-lo. O benefício de rsync é que ele copiará apenas os bits que foram alterados entre os arquivos locais e remotos. No entanto, uma pequena alteração local pode resultar em um arquivo compactado muito diferente, portanto, não faz sentido usar rsync para isso. Isso só complica as coisas sem nenhum benefício. Apenas use ssh direto como mostrado acima. Se você realmente quiser fazer isso, você pode tentar dar um subshell como um argumento para rsync . No meu sistema, eu não consegui fazer isso funcionar com 7za porque ele não permite que você grave dados compactados em um terminal. Talvez sua implementação seja diferente. Tente algo como ( isso não funciona para mim ):

    rsync $(tar cf - MyBackups | 7za a -an -txz -si -so) \
      user@server:/path/to/backup
    
  • Outro ponto é que 7z não deve ser usado para backups no Linux . Conforme indicado na página 7z man:

    DO NOT USE the 7-zip format for backup purpose on Linux/Unix because :
    - 7-zip does not store the owner/group of the file.

por 30.03.2013 / 04:00
9

Eu acho que esse comando vai fazer o truque

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

EDIT: uma versão anterior estava com duas opções "f" erradas.

Agora, antes de tudo, você precisa executar esse comando a partir do host de destino. E detalhes a serem explicados:

  1. ssh user @ host abrirá a conexão com a máquina host, de onde os dados devem ser transferidos.
  2. cd / path / to / data irá para o diretório onde os dados necessários são armazenados
  3. tar zc * iniciará a compactação e a colocará no STDOUT
  4. Agora pipe (|) pipeline o STDOUT da origem para o STDIN do destino em que "tar zx" está em execução e o fluxo de dados de descompactação é proveniente da origem.

Como você pode ver, este comando comprime durante a operação e economiza largura de banda. Você também pode usar outras compactações para obter melhores resultados, mas lembre-se de que compactação e descompactação exigem ciclos de CPU.

Referência

    
por 28.08.2015 / 20:55
2

Pequena melhoria para a resposta do dkbhadeshiya : você não tem que fazer cd dir , apenas especifique o trabalho diretório para o tar :

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

Você também pode fazer o upload do diretório da mesma maneira:

tar zc directory_name/ | ssh user@host "tar zx -C /new/path/to/data/"
    
por 27.04.2018 / 19:34

Tags