Baixe arquivos em pedaços com o DCDownloader
Publicado por Davidson Francis (última atualização em 11/04/2014)
[ Hits: 18.913 ]
O Divide and Conker Downloader (não, não é da Detective Comics, kkk) permite que o download de um arquivo (em link direto) possa ser dividido em n partes de modo que o usuário possa literalmente dividir o download em fragmentos.
Vejo no mínimo duas utilidades interessantes:
- Quando é necessário baixar arquivos realmente grandes e você dispõe de mais de uma conexão com a internet.
Desta forma um arquivo de 10 GB poderia ser facilmente distribuído entre 10 amigos, cada um deles baixando partes diferentes do mesmo arquivo simultaneamente; no término do download, basta fazer a junção das partes e obterá o arquivo original novamente.
- Quando o servidor limita a banda, com o uso de downloads simultâneos pode obter um aproveitamento muito maior da internet em questão. O que ilustro nesse vídeo: https://www.youtube.com/watch?v=aG59N51cWAQ
O script possui basicamente três comandos:
-g url qtd - Nesta opção geramos os arquivos de configuração que serão utilizados em cada máquina separadamente, onde:
url é o link do download e qtd é quantidade de máquinas e/ou instâncias que serão executadas.
-r file - Realiza a leitura do arquivo de configuração, onde file é o arquivo gerado pela opção "-g". Deve-se atentar ao executar o download em pastas separadas, devido aos arquivos auxiliares gerados no processo.
-j - Realiza o "join" de todos os arquivos baixados em um único arquivo.
Um exemplo de uso seria:
$ ./DCDownloader.sh -g http://link/file.tar.gz 2
PC1:
$ ./DCDownloader.sh -r DC1.conf
PC2:
$ ./DCDownloader.sh -r DC2.conf
Posteriormente:
$ ./DCDownloader -j
É isso pessoal, espero que tenham gostado e fico a disposição a quaisquer dúvidas, críticas e sugestões.
#!/bin/bash
clear
echo "------------------------------------------------"
echo " Divide and Conker Downloader, by Theldus"
echo "------------------------------------------------"
echo ""
gerarConfiguracao()
{
#Verifica se quantidade e valida
tam=`curl -sI $1 | grep Content-Length | cut -d ' ' -f 2 | sed 's/\r$//'`
tam=`echo "scale=2;$tam/1048576" | bc`
tam=`echo "$tam/$2" | bc`
if [ $tam -lt 1 ]; then
echo "> Por favor, entre com uma distribuicao >= 1MB por execucao"
else
#Distribuicao de blocos OK
if [ $2 -lt 2 ]; then
echo "> Escolha algo >=2"
else
if [ $2 -eq 2 ]; then
#Processa = 2,gera config e inicio e fim
rm DC1.conf 2>/dev/null
rm DC2.conf 2>/dev/null
#Inicio
echo "start" >> DC1.conf
echo $tam >> DC1.conf
echo $1 >> DC1.conf
echo "1" >> DC1.conf
#Final
echo "final" >> DC2.conf
echo $tam >> DC2.conf
echo $1 >> DC2.conf
echo "2" >> DC2.conf
echo "> Arquivos de configuracao gerados com sucesso"
echo "> $[tam*$2] MB divididos em $2 partes de $tam MB cada, :D"
echo -e "> Use o arquivo de configuracao para o download individual\n em cada pc"
else
#Processa > 2
rm DC*.conf 2>/dev/null
#Start
echo "start" >> DC1.conf
echo $tam >> DC1.conf
echo $1 >> DC1.conf
echo "1" >> DC1.conf
quantidade=$[$2-2]
indice=2
tam_ac=$tam
#Middle
while [ $quantidade -gt 0 ]
do
echo "middle" >> DC$indice.conf
echo $tam_ac >> DC$indice.conf
echo $[tam_ac+tam] >> DC$indice.conf
echo $tam >> DC$indice.conf
echo $1 >> DC$indice.conf
echo $indice >> DC$indice.conf
quantidade=$[quantidade-1]
indice=$[indice+1]
tam_ac=$[tam_ac+tam]
done
#Final
echo "final" >> DC$indice.conf
echo $tam_ac >> DC$indice.conf
echo $1 >> DC$indice.conf
echo $indice >> DC$indice.conf
echo "> Arquivos de configuracao gerados com sucesso"
echo "> $[tam*$2] MB divididos em $2 partes de $tam MB cada, :D"
echo -e "> Use o arquivo de configuracao para o download individual\n em cada pc"
fi
fi
fi
}
lerConfiguracao()
{
if [ -e "$1" ]; then
#Verifica o tipo do .conf para processamento individual
tipo=`head -n1 $1`
echo "Caso esteja executando em uma mesma maquina todos os arquivos de"
echo "configuracao, atente-se em executar o script em pastas diferentes!"
echo "OK?"
read trash
if [ "$tipo" == "start" ]; then
#Processa inicio
tam=`head -n2 DC1.conf | tail -n1`
url=`head -n3 DC1.conf | tail -n1`
fileName=`echo $url | tr "/" "\n" | tail -n1`
echo "PC 1, baixando..."
rm wget-log* 2>/dev/null
rm $fileName 2>/dev/null
pid=`wget -b $url | head -n1 | sed 's/[^0-9]//g'`
while [ ! -f $fileName ]
do
#Sim, nao faz nada,apenas para obter o delay necessario
#antes de verificar se arquivo existe
echo "nop" > /dev/null
done
while [ $[`wc -c $fileName | cut -d' ' -f1`/1048576] -lt $tam ]
do
echo -e "`tail -n1 wget-log`"
sleep 1
done
kill $pid
echo "Download concluindo, limando..."
dd if=./$fileName of=./DCDpc1 bs=1M count=$tam 2>/dev/null
rm $fileName
rm wget-log* 2>/dev/null
echo "Parte 1 concluida com sucesso, ;)"
else
if [ "$tipo" == "middle" ]; then
tamStub=`head -n2 $1 | tail -n1`
tamBaix=`head -n3 $1 | tail -n1`
tamBloco=`head -n4 $1 | tail -n1`
url=`head -n5 $1 | tail -n1`
fileName=`echo $url | tr "/" "\n" | tail -n1`
position=`tail -n1 $1`
#Gera um 'stub'
rm $fileName 2>/dev/null
dd if=/dev/zero of=./$fileName bs=1M count=$tamStub 2>/dev/null
echo "PC $position, baixando..."
rm wget-log* 2>/dev/null
pid=`wget -b -c $url | head -n1 | sed 's/[^0-9]//g'`
while [ ! -f "wget-log" ]
do
#Sim, nao faz nada,apenas para obter o delay necessario
#antes de verificar se arquivo existe
echo "nop" > /dev/null
done
while [ $[`wc -c $fileName | cut -d' ' -f1`/1048576] -lt $tamBaix ]
do
echo -e "`tail -n1 wget-log`"
sleep 1
done
kill $pid
echo "Download concluindo, limando..."
dd if=./$fileName of=./DCDtmp$position bs=1M ibs=1M skip=$tamStub 2>/dev/null
rm $fileName 2>/dev/null
dd if=./DCDtmp$position of=./DCDpc$position bs=1M count=$tamBloco 2>/dev/null
rm DCDtmp$position 2>/dev/null
rm wget-log* 2>/dev/null
echo "Parte $position concluida com sucesso, ;)"
else
if [ "$tipo" == "final" ]; then
tam=`head -n2 $1 | tail -n1`
url=`head -n3 $1 | tail -n1`
fileName=`echo $url | tr "/" "\n" | tail -n1`
position=`tail -n1 $1`
#Gera um 'stub'
rm $fileName 2>/dev/null
dd if=/dev/zero of=./$fileName bs=1M count=$tam 2>/dev/null
echo "PC $position, baixando..."
rm wget-log* 2>/dev/null
pid=`wget -b -c $url | head -n1 | sed 's/[^0-9]//g'`
while [ ! -f "wget-log" ]
do
#Sim, nao faz nada,apenas para obter o delay necessario
#antes de verificar se arquivo existe
echo "nop" > /dev/null
done
while [ -n "`pgrep wget | grep $pid`" ]
do
echo -e "`tail -n1 wget-log`"
sleep 1
done
echo "Download concluindo, limando..."
dd if=./$fileName of=./DCDpcFinal bs=1M ibs=1M skip=$tam 2>/dev/null
rm $fileName 2>/dev/null
rm wget-log* 2>/dev/null
echo "Parte $position concluida com sucesso, ;)"
fi
fi
fi
else
error
fi
}
Join()
{
echo "Antes de iniciar-mos o merge, certifique-se de que todos os arquivos"
echo "estao em um mesmo diretorio!"
echo "OK?"
read trash
echo "Juntando downloads..."
cat DCDpc* > DCDFinal
echo "Arquivo finalizado: DCDFinal, tenha um bom dia!"
}
error()
{
echo "-----------------------------------------------------------------------------"
echo "Parametros incorretos:"
echo "DCDownloader [operando] -g, -r"
echo "-g url quantidade - (Gera os arquivos de configuracao para cada download)"
echo "-r DCx.conf - (Le o x-esimo arquivo de configuracao para efetuar o"
echo " download)"
echo "-j - (Junta as partes em um unico arquivo novamente)"
echo "-----------------------------------------------------------------------------"
}
if [ "$1" == "-g" ]; then
gerarConfiguracao $2 $3
else
if [ "$1" == "-r" ]; then
lerConfiguracao $2
else
if [ "$1" == "-j" ]; then
Join
else
error
fi
fi
fi
Conversor do VMware para o VirtualBox
Script de monitoracao de servicos
Script simples para fazer backup em fita DAT
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
[Resolvido] VirtualBox can't enable the AMD-V extension
Como verificar a saúde dos discos no Linux
Como instalar , particionar, formatar e montar um HD adicional no Linux?
Como automatizar sua instalação do Ubuntu para desenvolvimento de software.
Não consigo instalar distro antiga no virtualbox nem direto no hd (15)
Quais os códigos mais dificeis que vcs sabem fazer? (12)
systemd-resol... precisa ser reiniciado periodicamente [RESOLVIDO] (7)









