Ferramenta de backup do HD para dispositivos externos
Publicado por Luis Henrique Pessoa (última atualização em 22/02/2017)
[ Hits: 3.217 ]
Este é um script simples feito em bash que utiliza as ferramentas zenity e rsync (que já vem em muitas distribuições) e foi feito para backup de dados pessoais (fotos, músicas, documentos, arquivos, etc) de um computador doméstico para um dispositivo externo (HD externo, pendrive, cartão de memória, etc).
1) O que o script não faz ou quando não é recomendado:
1.1) Execução de forma agendada, pois é interativo;
1.2) Copia para volumes de rede e/ou criptografados. Apesar do rsync permitir estes recursos, não fiz este teste;
1.3) Sincronização dos 2 lados. O rsync também permite isso, mas não é o caso desta ferramenta (pelo menos nesta versão);
1.4) Backup de arquivos de programas e/ou componentes sistema operacional. Mexer nestes arquivos com os programas em execução pode gerar resultados indesejáveis. Para isso utilize ferramentas como clonezilla e faça um backup do teu sistema;
RESUMINDO: script recomendado apenas para backup de documentos pessoais sentido computador doméstico (PC, notebook, etc) para dispositivos externos plugados.
2) Requisitos
2.1) shell: bash ou compatível
2.2) ferramentas: rsync e zenity (presentes nativamente no ubuntu)
3) preparação
3.1) Primeiro definir 2 diretórios:
3.1.1) diretório onde o script irá rodar (Ex: $HOME/scripts)
3.1.2) diretório onde ficarão os links do que será backupeado (Ex: $HOME/backups/rsync)
3.2) No diretório dos links de backup (item 3.1.2), criar os links para as pastas e arquivos que você deseja fazer backup:
No meu caso, estou criando links simbólicos, com este comando:
ln -s <diretorio_origem> link
Se os locais que você quiser copiar estiver em um hd diferente de onde roda a aplicação, aí você deve usar hardlinks, dúvidas? consulta o bom e velho man ln!
Um exemplo de como ficou meus links de backup:
luis@jupiter:~/backups/rsync$ ll
drwxrwxr-x 2 luis luis 4096 Dez 21 13:03 ./
drwxrwxr-x 5 luis luis 4096 Nov 12 09:19 ../
lrwxrwxrwx 1 luis luis 30 Jul 15 17:54 arquivos -> /home/data/restricted/arquivos/
lrwxrwxrwx 1 luis luis 17 Jul 15 20:09 clouds -> /home/luis/clouds/
lrwxrwxrwx 1 luis luis 29 Jul 15 17:54 imagens -> /home/data/restricted/imagens/
lrwxrwxrwx 1 luis luis 28 Jul 15 17:55 musica -> /home/data/restricted/musica/
-rw-rw-r-- 1 luis luis 90 Jul 3 16:38 readme.txt
lrwxrwxrwx 1 luis luis 28 Jul 15 17:55 videos -> /home/data/restricted/videos/
E este arquivo readme.txt, tem algum problema com ele? Nenhum, o script só leva em conta os links deste diretório.
4) Configurando o programa: aqui a gente vai editar algumas linhas do programa para adaptar ao seu ambiente.
4.1) Definição de alguns diretórios: preenche estas 3 variáveis com os diretórios em 3.1 e o diretório onde é montado suas mídias externas (no meu caso em /media/luis)
#
# definição de paths:
#
# $PATH_APP : onde roda o aplicativo
# $PATH_OR_BACKUP : diretório com os links para volumes a serem backupeados
# $PATH_MIDIAS : local onde são montadas as mídias de backup
PATH_APP=/home/$NAME_USER/scripts
PATH_OR_BACKUP=/home/$NAME_USER/backups/rsync
PATH_MIDIAS=/media/$NAME_USER
4.2) Sintaxe do comando rsync que você vai utilizar, neste meu caso ele copia (ou atualiza) os diretórios selecionados no dispositivo externo, deixando-os iguais e só gera alguma mensagem de andamento do backup se houver algum erro.
# definição do comando rsync
RSCMD="/usr/bin/rsync -auq --delete"
4.3) Seleção do que copiar: esta parte é opcional. Antes de iniciar a cópia, é gerada uma caixa de díálogo perguntando quais itens você deseja copiar. Dependendo do tamanho de cada diretório e de teus dispositivos, você pode deixar alguns itens previamente selecionados.
Para configurar isso basta editar este trecho do código:
# itens backpeados por default (opcional)
lista_bkp_def="imagens musica arquivos"
# configuração de lista para dispositivo específico
if [ "${DISP}" = "hde_lua" ];then
lista_bkp_def="imagens musica arquivos"
elif [ "${DISP}" = "hde_io" ];then
lista_bkp_def="imagens musica arquivos"
elif [ "${DISP}" = "hde_europa" ];then
lista_bkp_def="imagens musica arquivos videos"
elif [ "${DISP}" = "hde_titan" ];then
lista_bkp_def="imagens musica arquivos videos"
fi
Na variável $lista_bkp_def eu defino quais itens vão ficar selecionados para backup. Esta lista pode mudar de acordo com os nomes dos rótulos dos dispositivos, que estão nos if's do código.
obs: pelo gerenciador de arquivos (nautilus) é possível configurar os rótulos dos dispositivos.
5) Execução
Terminado os preparativos, agora vamos rodar. Plugue um disposivo externo e faça um teste.
Não esquecer de setar a permissão de execução: chmod u+x bkp2hde.sh
obs: se durante a execução você receber esta mensagem "Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.", não tem problema, pode continuar normalmente. É só um aviso do zenity.
5.1) Iniciando: ./bkp2hde.sh
5.2) É aberta uma caixa de diálogo (zenity) com os nomes dos dispositivos, se não tiver o dispositivo que você plugou, veja se você configurou a variável $PATH_MIDIAS corretamente (4.1). Após você escolher o dispositivo vem esta mensagem:
luis@jupiter:~/scripts$ ./bkp2hde.sh
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
Dispositivo "hde_io" selecionado.
Identificado o dispositivo:hde_io...
Tecle <ctrl>+c para sair ou enter para para continuar
Pressione qualquer tecla.
5.3) É aberta uma caixa de diálogo (zenity) para seleção dos diretórios que serão copiados. Se eles não aparecerem, veja se você configurou a variável $PATH_OR_BACKUP corretamente (4.1). No meu caso, escolhi as pastas imagens e musicas. Vem então estas linhas com os teus parâmetros de backup.
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
21/12/2016 14:23:08;-----------------
21/12/2016 14:23:08;Configurações de backup
Dispositivo : hde_io
itens de backup : imagens musica
diret. destino : /media/luis/hde_io/backup_jupiter_luis
comando : /usr/bin/rsync -auq --delete
Tecle <ctrl>+c para sair ou enter para para iniciar
Tudo ok? Então pressione <enter> e é só aguardar
5.4) Andamento do backup: aparecem linhas como estas
21/12/2016 14:26:03;Início
21/12/2016 14:26:03;-------------------
21/12/2016 14:26:03;backpeando imagens
21/12/2016 14:26:13;-------------------
21/12/2016 14:26:13;backpeando musica
21/12/2016 14:28:20;Concluido
Esta última linha indica que o backup teve sucesso
5.5) No dispositivo externo aparece este diretório na raiz:
./backup_<hostame>_<user>
Ex: no meu caso ficou assim ./backup_jupiter_luis
Então se você rodar este script em outra máquina, vai armazenar os arquivos em diretórios diferentes.
6) Atualizações que pretendo fazer futuramente:
6.1) Ao selecionar os diretórios para backup, mostrar o espaço que eles ocupam;
6.2) Ao selecionar as mídias de backup, mostrar a ocupação e o espaço disponível;
6.3) Testar em dispositivos externos de rede;
6.4) Gerar versão não interativa, podendo passar os argumentos de backup através de comando de linha ou arquivos de configuração
Então é isso, that's all folks! Espero que lhe ajudem! _/\_
#!/bin/bash
# programa      : bkp2hde.sh
# objetivo      : backup de volumes do hd para dispositivo externo
# autor         : lp (Luís Pessoa)
# versão        : 0.2.0b
# criação       : 16/07/2016
# dependências  : rsync e zenity
# manutenção    :
#     lp; 21/12/2016; escolha dos volumes a serem backpeados pelo zenity
###############
# functions
###############
###########
# function    : lu_echo
# description : echo improved with more information 
# usage       : lu_echo $msg [$tag01,$tag02,..]
# output      : echo <tags>;<date>;<msg>
# obs         : if tags was separeted by spaces or ; will be replaced by ,
function lu_echo {
    lu_echo_msg=$1
    lu_echo_tags=$2
    lu_echo_date=$(date +'%d/%m/%Y %H:%M:%S')
    
    if [ -z $lu_echo_tags ] ; then
       lu_echo_tags="${lu_echo_date}"
    else
       lu_echo_tags="${lu_echo_tags};${lu_echo_date}"
    fi   
    
    echo "${lu_echo_tags};${lu_echo_msg}"
}
###############
# end functions
###############
####################
# Settings 
####################
# pode variar dependendo do shell ou distribuição
NAME_HOST=$(hostname)
NAME_USER=${USER}
if [ -z ${NAME_HOST} -o -z ${NAME_USER} ];then
   echo "Redefina corretamente estas variáveis do sistema:"
   echo "NAME_HOST " $NAME_HOST
   echo "NAME_USER " $NAME_USER
fi 
#
# definição de paths: 
#
# $PATH_APP         : onde roda o aplicativo
# $PATH_OR_BACKUP   : diretório com os links para volumes a serem backupeados
# $PATH_MIDIAS      : local onde são montadas as mídias de backup
PATH_APP=/home/$NAME_USER/scripts
PATH_OR_BACKUP=/home/$NAME_USER/backups/rsync
PATH_MIDIAS=/media/$NAME_USER
#
# Seleção do dispositivo e path de destino de backup
#
LIST_MEDIAS=""
for item in `ls $PATH_MIDIAS`;do 
    LIST_MEDIAS="${LIST_MEDIAS}${item}\
"
done
DISP=`zenity --list \
  --title="Escolha o dispositivo de gravação" \
  --column="Dispositivo" \
"${LIST_MEDIAS}"`
case $? in
         0)
                echo "Dispositivo \"$DISP\" selecionado.";;
         1)
                echo "Nenhum dispositivo foi selecionado"
                exit 1
                ;;
        -1)
                echo "Ocorreu um erro na seleção do dispositivo"
                exit 1
                ;;
esac
PATH_DISP="${PATH_MIDIAS}/${DISP}"
PATH_DST_BACKUP="${PATH_DISP}/backup_${NAME_HOST}_${NAME_USER}"
# definição do comando rsync
RSCMD="/usr/bin/rsync -auq --delete"
##############
# checks 
##############
echo "Identificado o dispositivo:${DISP}..."
echo "Tecle <ctrl>+c para sair ou enter para para continuar " ; read
# verifica se o dispositivo está montado
if [ ! -d ${PATH_DISP} ];then
   echo "dispositivo ${DISP} não montado"
   exit 1
fi
# cria pasta backup de destino se não existir
if [ ! -d ${PATH_DST_BACKUP} ];then
   echo "criando pasta de deistino ${PATH_DST_BACKUP}"
   mkdir ${PATH_DST_BACKUP}
   [ $? -ne 0 ] && echo "Erro na criação de diretório" && exit 1
fi
########
# escolha dos locais que serão backupeados de acordo com o
# dispositivo deve ser estar nos if's abaixo
########
# itens backpeados por default (opcional)
lista_bkp_def="imagens musica arquivos"
# configuração de lista para meus dispositivos específicos
if [ "${DISP}" = "hde_lua" ];then
    lista_bkp_def="imagens musica arquivos"
elif [ "${DISP}" = "hde_io" ];then
    lista_bkp_def="imagens musica arquivos"
elif [ "${DISP}" = "hde_europa" ];then
    lista_bkp_def="imagens musica arquivos videos"
elif [ "${DISP}" = "hde_titan" ];then
    lista_bkp_def="imagens musica arquivos videos"                            
fi
# montando itens da coluna options
lista_opt=""
for elm in `ls "${PATH_OR_BACKUP}"`;do
    # filtra os arquivos que não são links
    if [ ! -L "${PATH_OR_BACKUP}/${elm}" ] ; then
        continue
    fi
    
    # verifica se link está na relação default
    is_check="FALSE"
    echo "${lista_bkp_def}" | grep -q "${elm}"
    if [ $? -eq 0 ] ; then
        is_check="TRUE"
    fi
    
    # montando lista de opções
    lista_opt="${lista_opt}${is_check} ${elm} "
done
# aborta se lista estiver vazia
[ -z "${lista_opt}" ] && echo "Lista de volumes de backup vazia. Verifique o diretório ${PATH_OR_BACKUP}" && exit 1
lista_bkp=$(zenity  --list  --text "Escolha os volumes para backup" --checklist  --column "Check" --column "Volumes" \
${lista_opt} --separator=" ")
case $? in
         1)
                echo "Lista de volumes para backup não selecionada"
                exit 1
                ;;
        -1)
                echo "Ocorreu um erro na seleção de volumes de backup"
                exit 1
                ;;
esac
#  última checagem antes do back-up
lu_echo "-----------------"
lu_echo "Configurações de backup"
echo "Dispositivo     : ${DISP}"
echo "itens de backup : ${lista_bkp}"
echo "diret. destino  : ${PATH_DST_BACKUP}"
echo "comando         : ${RSCMD}"
echo ""
echo "Tecle <ctrl>+c para sair ou enter para para iniciar " ; read
# loop de backups
lu_echo "Início"
for elm in ${lista_bkp};do
   lu_echo "-------------------"
   lu_echo "backpeando ${elm} "
   # tratando origem
   path_org="${PATH_OR_BACKUP}/${elm}"
   if [ ! -d ${path_org} ];then
       lu_echo "diretório de origem ${path_org} não encontrado"
       exit 1
   fi
   
   # tratando destino
   path_dst="${PATH_DST_BACKUP}/${elm}"
   if [ ! -d ${path_dst} ];then
       lu_echo "criando diretório de destino ${path_dst}"
       mkdir -p ${path_dst}
       [ $? -ne 0 ] && echo "Erro na criação de diretório" && exit 1
   fi
   
   # executando back-up
   ${RSCMD} ${path_org}/ ${path_dst}
   if [ $? -ne 0 ];then
      lu_echo "erro no backup de ${elm}. Tecle <ctrl>+c para sair ou enter para continuar"
      read
   fi
done
lu_echo "Concluido"
Script Backup com Log e envio por Email
Backup dinâmico de banco de dados MySQL
Nenhum comentário foi encontrado.
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
Problemas com Driver NVIDIA (5)
Warcraft II Remastered no Linux? (8)
Instalação dualboot Windows 11 e Debian 13 (7)









