O mundo é sempre colorido, quando tudo funciona bem. Porem o que fazer quando necessitamos fazer uma determinada tarefa e as coisas não funcionam como esperado .
Necessitei fazer uma coisa bem simples, um BACKUP, para falar a verdade, uma simples copia de arquivos .
O problema, eu necessitava fazer o backup, não de um, não de uma dezena, nem uma centena de arquivos.
Eu necessitava fazer o BaCkup de mais de 2 milhões de arquivos. Esse arquivos estão em 16 diretórios, bem estruturados.
Tudo deveria ser simples, porem as ferramentas começam a falhar quando falamos de coisas de quantidades grandes. Cada diretório desses tem aproximadamente 250 mil arquivos ( é .. a conta chega a 4 milhões )
Para essa tarefa eu ja havia utilizado o RSYNC do linux com grande sucesso, porem desta vez alguma coisa deu errado. Havia um (ou mais) arquivos com erro de leitura.
Fui descobrir depois de longas horas que o RSYNC não trata esse tipo de erro, simplesmente indica o erro e para. (Li o MAN, procurei no Google e nada, se alguem souber o parametro magico, favor me informar)
Ai não teve jeito... eu tinha que resolver meu problema. Mais uma vez tive que improvisar.
Situação:
2 drives removiveis, um do tipo NAS e outro USB
Juro que tentei fazer pelo Windows, porem o Windows desistiu durante a contagem de arquivos e tempo. Talvez o powershell resolva isso, mas ... A melhor ferramenta é sempre aquela que voce sabe usar, assim...
O que eu necessito :
1. copiar arquivos de um lado para o outro
2. descobrir quais são os arquivos a serem copiados
2.1 arquivos em vários diretório
3. não copiar arquivos que ja existem no diretório/drive destino.
Solução A:
1. Listar arquivos: comando FIND do linux
2. copiar arquivos: comando CP do linux
Se fosse só isso poderiamos resolver o problema com FIND, AWK e CP
Porem eu queria evitar copias desnecessárias.
Solução P:
Resolvi fazer um pequeno programa em PERL para resolver meu problema
01- #!/usr/bin/perl 02- 03- $origen = $ARGV[0]; 04- $destino = $ARGV[1]; 05- 06- $exec = `find $origen -type f`; 07- 08- @files = split(/\n/,$exec); 09- 10- foreach $file (@files) { 11- $dfile = $destino."/".$file; 12- if (-e $dfile){ 13- print "$file EXISTE em $dfile\n"; 14- next; 15- }else{ 16- print "Copiando : $file para $dfile\n"; 17- $exec = `cp $file $dfile`; 18- } 19- } |
O programa é simples, recebo 2 parametros, origem e destino ( linhas 03 e 04 )
Mando o PERL executar o comando find do Linux ( linha 06 )
Coloco o resultado (arquivos encontrados) em um Vetor ( linha 08)
Listo o vetor (10)
Monto a linha onde deverá estar o arquivo destino (11)
Agora... linha 12 . Essa linha testa se o arquivo existe.
Agora ficou facil. Se existir, pula para o Proximo (14)
Se não copie o arquivo origem para o lugar onde eu quero ele (17)
root@WingChun:/mnt3/var/base/d# /mnt3/var/scripts/psync.pl . /mnt2/var/base/d/ Copiando : ./df/dff/dff6af87ee2e15b3745b3e67592e79962f13f1a0 para /mnt2/var/base/d//./df/dff/dff6af87ee2e15b3745b3e67592e79962f13f1a0 Copiando : ./df/dff/dff6b06d6eec0d5d1db0e89bcc1d1f7f462acecf para /mnt2/var/base/d//./df/dff/dff6b06d6eec0d5d1db0e89bcc1d1f7f462acecf Copiando : ./df/dff/dff6b38b80dcf68e6aa0d9e3cd41f6e7af207938 para /mnt2/var/base/d//./df/dff/dff6b38b80dcf68e6aa0d9e3cd41f6e7af207938 |
Não tomei nenhum cuidado de programação segura, assim não venham me criticar.
E voces? ainda acham que Segurança Importa ?
Abraços