Português do Brasil English
Devin no Facebook  Devin no Twitter  RSS do Site 
Linux    

Cópias remotas de arquivos


Comentários  11
Visualizações  
214,599

Uma das tarefas mais comuns de um administrador de sistemas é fazer cópias remotas de arquivos – ou seja – de uma máquina para outra. Em rede, isto pode ser feito de diversas maneiras, como por exemplo: FTP, HTTP, SSH, RSYNC, entre outros. Este artigo mostra as principais formas de fazer isso. Vou tentar ser o mais direto possível.

Vamos usar aqui dois servidores exemplo:

  • servidor1.example.com (192.168.0.1)
  • servidor2.example.com (192.168.0.2)

SSH

O protocolo do SSH é seguro o suficiente para fazer cópias entre servidores em uma rede e é sempre o protocolo recomendado. Vamos agora para como fazer isso:

Copiando um arquivo simples de uma máquina para outra

servidor1$ scp maluco@servidor2.example.com:~/arquivo.txt ./

O comando acima copia o arquivo.txt do HOME (~) do usuário maluco, do servidor2 para o diretório atual do servidor1. Bem parecido com o comando cp.

Copiando todo um diretório de uma máquina para outra

servidor1$ scp -r maluco@servidor2.example.com:/home/maluco /tmp

Ou seja, copio o diretório maluco do servidor2 para a máquina atual, no diretório /tmp.

servidor1$ scp -Cpr maluco@servidor2.example.com:/home/maluco /tmp

O parâmetro -C agora faz a mesma ação anterior, só que agora compactando os dados antes de enviar pela rede. O ssh usa formato gzip e pode-se usar essa opção caso se queira economizar na banda de rede.

O parâmetro -p preserva todos modos e timestamps de arquivos, ideal para fazer uma cópia mais exata.

Usando o tar e o ssh para cópias mais exatas ainda

Por exemplo, um backup de sistema. O tar é ótimo para criar um arquivamento que preserva todas as permissões, usuários e grupos donos, modos, links simbólicos, etc. Desse jeito dá pra juntar os dois:

servidor1$ tar -cpzf - /etc | ssh maluco@servidor2.example.com "cat > /var/lib/backup/servidor1-etc.tar.gz"

O comando acima vai compactar o diretório /etc, só que ao invés de jogar o resultado em um arquivo, joga como STDIN, que o comando ssh pega e executa no servidor2 o comando cat, que por sua vez pega o STDIN e joga para o arquivo /var/lib/backup/servidor1-etc.tar.gz.

Em outras palavras, ele compacta o diretório /etc e já joga no outro servidor direto. Isso economiza tempo e espaço no servidor origem.

servidor1$ tar -C /home -cpzf - maluco | ssh maluco@servidor2.example.com "tar -C /home -xpzf -"

Agora ao invés de usar o cat, ele jogou diretamente o diretório na máquina remota, descompactado. É parecido com a opção -rp do scp, só que com a vantagem do tar: preserva modos, permissões, donos, links, etc.

Para mais informações sobre STDIN, STDOUT, pipes (|), tenho um outro artigo falando sobre isso.

HTTP e FTP

A primeira coisa que você precisa saber é que eu não vou ensinar a compartilhar os arquivos por HTTP e FTP neste artigo. É um assunto totalmente diferente, então vamos assumir que você já tenha os arquivos servidos via HTTP ou FTP em algum lugar :)

Pra quem já é um pouco acostumado com esses protocolos, um programa sempre vem na mente: wget. Mas além dele também há um comando muito útil para fazer operações mais complexas: o lftp.

Pegando arquivos e páginas via HTTP/FTP

servidor1$ wget -c 'http://servidor2.example.com/arquivo.txt' -O /home/maluco/informacoes.txt

O comando acima pega o arquivo.txt do servidor1 e o escreve (-O) em /home/maluco/informacoes.txt. Se você não especificar o -O, ele coloca no diretório atual com o mesmo nome remoto (no caso, arquivo.txt). O -c é para ele tente continuar um download caso o arquivo já exista, e a não ser que você queira sobrescrever os arquivos destino, é bom sempre usar a opção.

servidor1$ wget -c -r 'http://www.devin.com.br'

Já este vai fazer uma cópia recursiva de todo o site www.devin.com.br. Isso inclui os links e imagens, que o wget pega automaticamente do código HTML.

Mirrors com lftp

E falando em recursividade, o lftp fornece ótimos recursos para fazer este tipo de download. Por exemplo, eu estou afim de criar um espelho interno do repositório de pacotes do CentOS. Vamos supor que eu tenha escolhido o mirror kernel.org, via HTTP:

servidor1$ lftp
lftp :~> open http://mirrors.kernel.org/centos/5.5/os/x86_64/
lftp mirrors.kernel.org:/centos/5.5/os/x86_64> mirror -verbose
[...]

O lftp se encarrega de examinar o diretório e pegar todo o seu conteúdo: arquivos e sub-diretórios, salvando no diretório atual. A opção –verbose vai mostrando na tela o que o lftp está fazendo (analizando os diretórios, baixando os arquivos…).

O mesmo pode ser feito com um comando só, um ótimo jeito para se fazer isso automaticamente em shell-scripts:

servidor1$ lftp -c "open http://mirrors.kernel.org/centos/5.5/os/x86_64/ && mirror --verbose"

Ou seja, com o parâmetro -c, consigo executar os dois comandos (conectar, fazer mirror) de modo não-interativo, e depois ele sai do programa (para não sair, usa-se o -e ao invés de -c). O mirror também analisa e continua os downloads de onde parou, caso precise.

A mesma coisa pode ser feita via FTP, vamos supor agora que é preciso também de usuário e senha…

servidor1$ lftp -c "open ftp://usuario:senha@mirrors.kernel.org/centos/5.5/os/x86_64/ && mirror --verbose"

O lftp ainda suporta uma porrada de opções. São centenas. Nesse caso, a manpage sempre ajuda (man lftp). Uma das opções que eu acho muito legal é a exclude. Com a opção exclude, eu consigo fazer um download recursivo, retirando arquivos com nomes que não quero. Por exemplo:

servidor1$ lftp -c "set mirror:exclude-regex '(\.svn|SRPMS)' && open ftp://mirrors.kernel.org/centos/5.5/os/ && mirror --verbose"

No comando acima, eu estou excluindo qualquer arquivo ou diretório que tenha o contenha o nome .svn ou SRPMS. Isso me faz baixar apenas os diretórios i386 e x86_64. Fácil não? Aí é só usar a imaginação. Os exemplos aqui são muito comuns na hora de criar espelhos de repositórios e arquivos entre sistemas.

Mirror reverso (upload de arquivos)

No caso de mirror de um mirror reverso, ao invés de pegar os arquivos de um sistema remoto, eu coloco os arquivos no sistema remoto. A sintaxe é praticamente a mesma:

servidor1$ lftp -c "lcd /var/lib/backup && open ftp://usuario:senha@servidor2.example.com/backup/ && mirror -R --verbose"

O que mudou aqui: o comando lcd vai para o diretório local, onde os arquivos se encontram. Depois eu abro uma conexão FTP com servidor2.example.com, utilizando um usuário e senha. Em seguida eu faço um mirror reverso (opção -R), que ao invés de fazer download dos arquivos, vai fazer upload. Simples dessa forma.

rsync

O rsync foi feito especialmente para você sincronizar os arquivos de dois lugares e por isso ele é otimizado para isso. Geralmente é utilizado para copiar diretórios e seus conteúdos da forma mais exata possível (preservando permissões, modos, timestamps). Além disso, antes de começar a copiar, ele analisa o destino (ou origem, dependendo do caso) e vê o que realmente tem que ser copiado. Se um arquivo já existe no destino, para que copiar de novo?

O rsync pode funcionar via protocolo próprio, ou via ssh. Se existe um servidor rsync, pode-se usar ele. Para criar um, vai um pouco fora do escopo deste artigo, mas não é tão complicado também. Na maioria das vezes, você vai querer usar o rsync via ssh, que é o caso mais comum.

Sincronizando um diretório no servidor remoto

servidor1$ rsync -e "ssh" -avr /var/lib/backup/ maluco@servidor2.example.com:/var/lib/backup/

No comando acima, utilizei o ssh (-e “ssh”) para fazer o transporte. As opções -avr copiam recursivamente (-r), mostrando tudo o que for sendo copiado (-v) e da forma mais exata possível, preservando (-a). Até aí tudo bem…

… Mas preste bastante atenção! O rsync é muito sensível com a barra no final da origem e destino. Então coloque isso na cabeça:

  • Quando não se usa a barra no final, o rsync copia o diretório e todo seu conteúdo;
  • Quando usar a barra no final, o rsync copia apenas o conteúdo do diretório.

Confuso? Eu também fiquei. No exemplo anterior, eu copiei o conteúdo do diretório backup (localizado em /var/lib) para o /var/lib/backup do servidor2. Isso significa que o diretório /var/lib/backup deve existir no servidor2, senão é capaz de dar erro. Ficou assim:

servidor2$ ls /var/lib/backup
1   11  13  15  17  19  20  22  24  26  28  3   31  33  35  37  39  40  42  44  46  48  5   6  8
10  12  14  16  18  2   21  23  25  27  29  30  32  34  36  38  4   41  43  45  47  49  50  7  9

E se eu tirar uma barra?

servidor1$ rsync -e "ssh" -avr /var/lib/backup maluco@servidor2.example.com:/var/lib/backup/

Nesse caso, olha só como ia ficar:

servidor2$ ls /var/lib/backup
backup

servidor2$ ls /var/lib/backup/backup
1   11  13  15  17  19  20  22  24  26  28  3   31  33  35  37  39  40  42  44  46  48  5   6  8
10  12  14  16  18  2   21  23  25  27  29  30  32  34  36  38  4   41  43  45  47  49  50  7  9

Como tirei a barra, ele também copiou o diretório backup, ao invés de apenas seu conteúdo. Então lembre-se sempre… Com barra: só conteúdo; Sem barra: diretório e conteúdo.

Assim como lftp, o rsync também aceita excluir arquivos por nome:

servidor1$ rsync -e "ssh" --exclude='.svn' -avr /var/www/html/aplicacao maluco@servidor2.example.com:/var/www/html

No comando acima, sincronizamos o diretório /var/www/html/aplicacao, mas excluindo qualquer operação com arquivos que tem no nome “.svn“. Uma prática muito comum por aí.

Por padrão, o rsync não remove arquivos e diretórios do destino. Isso significa que a sincronização é apenas em uma mão. Se no servidor1 novos arquivos surgirem, ou arquivos forem modificados, o rsync vai sincronizar. Mas se um arquivo ou diretório for removido, ele não será removido no servidor2. Para resolver isso, usa-se a opção –delete:

servidor1$ rsync -e "ssh" --exclude='.svn' --delete -avr /var/www/html/aplicacao maluco@servidor2.example.com:/var/www/html

Dessa forma você evita de ficar acumulando “lixo” no servidor2.


Comentários  11
Visualizações  
214,599


TagsLeia também

Apaixonado por Linux e administração de sistemas. Viciado em Internet, servidores, e em passar conhecimento. Idealizador do Devin, tem como meta aprender e ensinar muito Linux, o que ele vem fazendo desde 1997 :-)


Leia também



Comentários

11 respostas para “Cópias remotas de arquivos”

  1. syn disse:

    olá

    estou usando o cwrsync para sincronizar um diretório entre windows e linux e a opção '–delete' não está funcionando. a linha:

    rsync -avr –delete -e "ssh" windows linux

    alguma idéia do que pode ser:

  2. Tiago Cruz disse:

    Uma parada legal também é usar o NetCat com o PV, assim você consegue saber a quantas anda sua transferência =D

    pv will copy each supplied FILE in turn to standard output (- means standard input), or if no FILEs are specified just standard input is copied. This is the

    same behaviour as cat(1).

    A simple example to watch how quickly a file is transferred using nc(1):

    pv file | nc -w 1 somewhere.com 3000

    A similar example, transferring a file from another process and passing the expected size to pv:

    cat file | pv -s 12345 | nc -w 1 somewhere.com 3000

  3. gdardani disse:

    Po, sshfs e muito porco mas quebra muito o galho eim!

  4. Amaro Omena disse:

    Agradeço ajuda. Utilizo o lftp remotamente e tenho que deletar diretório muito grande e em outros casos deletar muitos arquivos. o comando rm -rf primeiramente copia todo diretório, e isso acaba não deletando os diretórios e arquivos. Com o comando mput eu resolvo o problema de copia do diretório, porque ele não copia como o mirror, e consigo enviar os arquivos, mas existem casos que preciso deletar pastas e muitos arquivos. Como deletar. Agradeço ajuda.

    Amaro

  5. Boa dica de backup. O problema é que os dados, enquanto armazenados não estão em criptografados. Se alguém entra e rouba o server, vão ter acesso aos dados. Depois, se alguém rouba o server de backup, não há procedimentos de backup offsite, para guardar o backup fora da empresa. Também dessa forma não há checagem de integridade de dados. Quando se usa um cp para copiar os dados, eles podem chegar do outro lado com defeito e não será feita nenhuma checagem disso (md5checksum) caso a mídia apresente algum defeito, um badblock, etc. O melhor mesmo é usar um sistema de backup, como o Nimbus Opensource Backup, GPL e prevê todas as boas práticas em backup. Está disponível em http://www.trynimbus.com grátis (GPL).

  6. veliz disse:

    Muy agradecido estoy Hugo abrzo Hermano…

  7. Felipe gabriel disse:

    Otimo!!!!
    só faltou usando CURL
    curl -T teste.jpg ftp://www.exemplo.com –user usuario:senha

  8. Socrates Martins disse:

    Bom dia,

    Tenho que copiar arquivos de um servidor x para minha pastas no HD externo , espetado na minha maquina local.
    Nao está funcionando.
    Tem como adicionar a senha no ssh, para facilitar ?

    #!/bin/bash/

    # Copiando Backup

    rsync -e "ssh" -Cavpt usuario1@192.168.0.24/Programas/ :/home/usuario2/Backup/
    shutdown -h 21:00

    • eitchugo disse:

      Pra logar automaticamente no ssh você vai ter que usar autenticação via chaves. Basicamente na *origem* você cria uma chave (caso não tenha feito) com o comando:

      ssh-keygen

      Depois copia o conteúdo do *id_rsa.pub* (chave pública) para o servidor *remoto*, no $HOME/.ssh/authorized_keys e dá permissão (chmod 600 $HOME/.ssh/authorized_keys). Então ele vai usar a chave para logar automagicamente.

      Artigos relacionados:

      SSH – Muito mais que um simples shell seguro

Deixe uma resposta