Ferramenta de backup do HD para dispositivos externos

Publicado por Luis Henrique Pessoa (última atualização em 22/02/2017)

[ Hits: 2.979 ]

Download bkp2hde.sh




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! _/\_

  



Esconder código-fonte

#!/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"

Scripts recomendados

Backup incremental com montagem automática e e-mail

Backup, Recuperação e Chroot

Backup com a ferramenta tar

Fazendo backup e compactando

BTRFS - Gerenciamento de snapshot por quantidade


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts