123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 |
- #!/usr/bin/bash
- #
- #-------HEADER---------------------------------------------------------------------|
- #AUTOR
- # Jefferson Rocha <lrcjefferson@gmail.com>
- #
- #
- #DATA DE CRIAÇÃO
- # 31/01/2018
- #
- #
- #LICENÇA
- # MIT
- # https://raw.githubusercontent.com/dunee/backup/master/LICENSE
- #
- #
- #DESCRIÇÃO
- # dunee é um simples programa em Shell com interface dialog para backup em sistema
- # GNU/Linux.
- # São necessárias algumas dependências para ser executado com exito, sendo elas:
- # (rsync, dialog, tar, xf, bash)
- #
- #
- #ARQUIVOS DE AJUDA.
- # -Todos arquivos estão localizados em /etc/dunee
- # menu-principal.txt
- # -Executavel se encontra em /usr/sbin
- #
- #
- #***NOTAS DE DESENVOLVIMENTO***
- # -Usar somente um comando por linha
- # -Usar somente 1 parâmetro no dialog por linha, não se importando com o tamanho
- # de linhas.
- # -Usar chamadas (funções, váriaveis, arrays) em inglês.
- # -Comentários devem ser em português do brasil.
- # -Se a linha é "complexa" deixe um comentário.
- # -Para condicionais '[ ]' ou 'test' simples, estamos em bash, use a nova sintaxe
- # '[[ ]]'
- #
- #
- #CHANGELOG
- # V0.1 (Jefferson Rocha)
- # Iniciado projeto em 31/01/2018
- #
- # V0.2 (Jefferson Rocha)
- # -Agora tem suporte a md5 no backup básico
- #
- # -Adicionado condicional no bloco (dir_if_backup e dir_of_backup) testa se os
- # diretorios tem permissão de Escrita.
- #
- # -Reformulado todo código, status de sáida estavam com problemas.
- #
- # -Adicionado opção para envio remoto com scp /Falta o recebimento.
- #
- # -Agora o programa tem logs em '/tmp', agora mostra os erros.
- #
- # -O bloco (básico) foi dividido em 3 funções para não repitir código no decorrer
- # do programa, os blocos são:
- # 'if_dir, of_dir e create_backup_basic' a chamada basic_mod ainda continua, para
- # fazer as chamadas das outras funções.
- #
- # -Adicionado no menu principal uma opção para verificar conectividade com
- # a internet.
- #
- #
- #TODO
- #-Falta adicionar o programa em inglês, a chave já tem rs.
- #-Falta adicionar a parte de Receber na opção Remoto
- #-------END-HEADER-----------------------------------------------------------------|
- #########################################################|
- #################### VÁRIAVEIS ##########################|
- #########################################################|
- name="dunee"
- version="0.2"
- back="$name Versão $version" # Titulo de fundo, para ser usado em --backtitle
- directory_root="/etc/dunee"
- log="/tmp/log.bkp"
- log_tags="/tmp/log_tags.bkp"
- #----CHAVES--------(bibibibi)
- lang="0" # 0 pt_BR / 1 en_US
- #----COMANDOS---------------
- date_bkp=$(date +%d-%m-%Y) # Para criar a extensão nome-DATA.bkp
- # Botões do dialog referente ao status de sáida.
- cancel_button="1"
- help_button="2"
- esc_button="255"
- #########################################################|
- #########################################################|
- ################# TESTES de inicialização ###############|
- #########################################################|
- # Não é portugues do brasil? então ative a chave en_US
- [[ "$LANG" = "en_US.UTF-8" ]] && lang="1"
- # Dialog existe?
- if [[ ! -e $(type -P dialog) ]]; then
- if [[ "$lang" -eq "1" ]]; then
- echo "DIALOG Not found..."
- else
- echo "Dialog não foi encontrado, instale e retorne."
- fi
- fi
- # scp existe?
- if [[ ! -e $(type -P scp) ]]; then
- if [[ "$lang" -eq "1" ]]; then
- echo "scp Not found..."
- ecrilse
- echo "Não encontrei o scp..."
- fi
- fi
- #########################################################|
- #########################################################|
- #################### FUNÇÕES ############################|
- #########################################################|
- # Tela de ajuda principial do programa.
- menu_welcome(){
- echo -e "\tpara ajuda digita !ajuda"
- }
- # Status global dos botões (cancel, help, esc)
- status(){
- case $? in
- "$cancel_button")
- dialog --title "$name" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "Deseja Sair?" 0 0
- [[ "$?" -eq "0" ]] && exit 0 ;;
-
- "$esc_button") echo "ESC, pressionado. :(" && exit 1 ;;
- esac
- }
- # TAR Opções
- execute_tar(){ tar -cvJpf "$@"; }
- # SCP Opções
- execute_scp(){
- scp -C ${choose_the_tag} -P "$port" "$dir_if_backup" "${user}@${ip}:${dir_send}"
- }
- if_dir(){
- while :; do
- name_backup=$(
- dialog --stdout \
- --title "IMPORTANTE!" \
- --backtitle "$back" \
- --cancel-label "Voltar" \
- --inputbox \
- "Digite o Nome final para o Backup.\nExemplo Slackjeff-dir" \
- 10 50 )
- [[ "$?" -eq "1" ]] && main # Apertou <VOLTAR> volta para o menu principal
- # Verificando se váriavel nome do backup não está nula, se estiver loop nele.
- if [[ -z "$name_backup" ]]; then
- dialog --title "OPS!" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox \
- "\nVocê deixou nulo o nome do seu Backup.\n" \
- 6 60
- else
- dialog --title "NOME DO BACKUP FINAL" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\n${name_backup}-${date_bkp}.bkp" \
- 6 40
- break
- fi
- done
-
- # Vamos selecionar o diretorio/arquivo de ORIGEM
- while :; do
- dir_if_backup=$(
- dialog --stdout \
- --title "SELECIONE O DIRETÓRIO/ARQUIVO DE 'ORIGEM'" \
- --backtitle "$back" \
- --cancel-label "Voltar" \
- --dselect "/" \
- 8 80 )
- if [[ "$?" -ne "0" ]]; then
- # Apertou não? então voltamos ao menu principal!
- dialog --title "RETORNANDO" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\nOK, retornando ao menu principal..." \
- 5 40
- main # Retornando ao menu principal
- fi
-
- if ! dialog --title "CONFIRMA?" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "Confirma o diretório de 'ORIGEM': $dir_if_backup" \
- 6 80
- then
- dialog --title "VOLTANDO" \
- --backtitle "$back" \
- --msgbox "Vamos retornar então." \
- 5 40
- else
- # Usuário tem permissão de Leitura ou escrita no diretorio?
- # Se tiver para o loop e continua, se não volta.
- if [[ ! -w "$dir_if_backup" ]] || [[ ! -r "$dir_if_backup" ]]; then
- text="\nSem permissões neste diretório...\n
- Escolha outro diretório, ou dê as devidas permissões para este diretório."
- dialog --title "SEM PERMISSÃO!" \
- --backtitle "$back" \
- --msgbox "$text" \
- 8 80
- else
- break # Digitou sim o loop para e continua :)
- fi
- fi
- done
- }
- of_dir(){
- while :; do
- # Agora vamos selecionar o diretorio/arquivo de DESTINO.
- dir_of_backup=$(
- dialog --stdout \
- --title "SELECIONE O DIRETÓRIO/ARQUIVO DE 'DESTINO'" \
- --backtitle "$back" \
- --cancel-label "Voltar" \
- --dselect "/" \
- 8 80 )
- # Conferindo se usuário confirma.
- if [[ "$?" -ne "0" ]]; then
- dialog --title "RETORNANDO" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\nOK, retornando ao menu principal..." \
- 5 40
- main # Retornando ao menu principal
- fi
-
- if ! dialog --title "CONFIRMA?" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "Confirma o diretório de 'DESTINO': $dir_of_backup" \
- 6 80
- then
- # Apertou não? então voltamos ao menu principal!
- dialog --title "VOLTANDO" \
- --backtitle "$back" \
- --msgbox "Vamos retornar então." \
- 5 40
-
- else
- # Usuário tem permissão de escrita no diretorio?
- # Se tiver para o loop e continua, se não volta.
- if [[ ! -w "$dir_of_backup" ]]; then
- text="\nSem permissão de ESCRITA neste diretório...\n
- Escolha outro diretório, ou dê permissão de ESCRITA 'w' para este diretório."
- dialog --title "SEM PERMISSÃO!" \
- --backtitle "$back" \
- --msgbox "$text" \
- 8 80
- else
- break # Digitou sim o loop para e continua :)
- fi
- fi
- done
- # Se não tem '/' barra no final adiciona, se ter não faz nada.
- dir_of_backup_bar="${dir_of_backup%/}/"
- }
- create_backup_basic(){
- # Gerando Backup, chamando a função (execute_tar)
- execute_tar "${dir_of_backup_bar}${name_backup}-${date_bkp}.bkp" "$dir_if_backup" 2> /dev/null | \
- dialog --title "CRIANDO BACKUP..." \
- --backtitle "$back" \
- --progressbox "Aguarde! criando backup em: $dir_of_backup_bar" \
- 22 100
- # TODO Se apertar ESC retorna 1, precisa arrumar para retornar
- # status 255 para ter uma tela de falha com status 1.
- # Por enqaunto está generico com o case.
- case $? in
- 1|130|255) status ;; # Monitoração, caso o usuário decida cancelar
-
- 0) # Usuário quer gerar MD5?
- if dialog --title "GERAR O MD5?" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "\nVocê deseja gerar o arquivo md5?" \
- 8 40
- then
- # Gerando MD5
- dialog --title "GERANDO MD5!" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\nAguarde, vamos gerar o md5 e finalizamos." \
- 8 40
-
- if md5sum "${dir_of_backup_bar}${name_backup}-${date_bkp}.bkp" > "${dir_of_backup_bar}${name_backup}-${date_bkp}.md5"
- then
- # Se deu tudo certo, mostramos a mensagem de ok e continuamos.
- dialog --title "CONCLÚIDO" \
- --backtitle "$back" \
- --msgbox \
- "\nConclúimos, o md5 foi gerado em: '${dir_of_backup_bar}'" \
- 8 40
- else
- dialog --title "OPS" \
- --backtitle "$back" \
- --msgbox "Aconteceu algum erro ;(" \
- 8 40
- main # Chamando função main.
- fi
- else
- dialog --title "CONTINUANDO" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\nOk, vamos continuar sem md5." \
- 6 40
- fi
-
- # Mensagem de finalização!
- text="Finalizamos...\n
- O arquivo '${name_backup}-${date_bkp}.bkp' está disponivel em '$dir_of_backup_bar'\n
- Deseja fazer mais backup?"
- if dialog --title "FINALIZADO!" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "$text" \
- 8 100
- then
- # Se for sim, voltamos a função principal e começa tudo de novo! :)
- main # Chamando o menu principal.
- else
- echo -e "\033[31;1m ${name}<3 \033[m"
- exit 0
- fi
- esac # Case do MD5
- }
- #########################################################|
- ################### MODO BÁSICO #########################|
- #########################################################|
- basic_mod(){
- #DIRETORIO DE ORIGEM
- if_dir # Chamada função de destino
- # Diretório de DESTINO
- of_dir # Chamada função de DESTINO
- # Criando Backup
- create_backup_basic # Chamada função para CRIAR backup, BÁSICO
-
- } # fecha função
- #########################################################|
- ################## MODO REMOTO ##########################|
- #########################################################|
- remote(){
- while :; do
- send_or_receive=$(
- local text="Escolha a opção que se adapta a você!\n
- -Para enviar um arquivo para um servidor remoto escolha a opção 'enviar'\n
- -Para receber um arquivo de um servidor remoto escolha 'receber'\n"
- dialog --stdout \
- --title "ENVIAR OU RECEBER?" \
- --backtitle "$back" \
- --ok-label "Confirma" \
- --cancel-label "Voltar" \
- --radiolist "$text" \
- 10 100 0 \
- "Enviar" "Envie seus backups para um servidor remoto" on \
- "Receber" "Receba seus backups de um servidor remoto" off \
- )
- [[ "$?" -eq "1" ]] && main # Aperto voltar, volta para o menu principal.
- # Conferindo se var não está nula, se não estiver para o loop.
- if [[ -z "$send_or_receive" ]]; then
- dialog --title "OPS!" \
- --backtitle "$back" \
- --msgbox "Selecione alguma opção!" \
- 0 0
- else
- break
- fi
- done
- case "$send_or_receive" in
- "Enviar") # Se for para enviar cai aqui! :)
- repete_form(){
- while :; do
- text="TEXTO AQUI"
- # Armazenando dados do formulário em seu devido lugar.
- { read user; read ip; read port; read dir_send; } \
- < <(dialog --stdout \
- --title "RESPONDA TODO FORMULÁRIO!" \
- --ok-label "Enviar" \
- --cancel-label "Voltar" \
- --backtitle "$back" \
- --form "$text" \
- 12 70 0 \
- "USUÁRIO:" 1 1 "" 1 13 35 0 \
- "IP HOST:" 2 1 "" 2 13 35 0 \
- "PORTA:" 3 1 "22" 3 13 10 0 \
- "DIRETORIO:" 4 1 "" 4 13 50 0 )
- # Conferindo status
- [[ "$?" -eq "1" ]] && main # retornando ao menu
-
- # Conferindo váriaveis se não estão nulas.
- if [[ -z "$user" ]] || [[ -z "$ip" ]] || [[ -z "$port" ]] || [[ -z "$dir_send" ]]; then
- text="\nParece que você deixou alguma informação nula!\n
- É de extrema importância vocẽ preencher todos os campos.\n
- Deseja retornar? e preencher os campos novamente?"
- if dialog --title "OPS!" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "$text" \
- 10 60
- then
- dialog --title "RETORNANDO" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\nVamos retornar." \
- 5 24
- else
- main
- fi
- else
- break
- fi
- done # Fecha while form
- # Verificando se usuário confirma os dados!
- text="\nConfirma os dados fornecido no formulário?\n\n
- Usuário: $user \n
- Ip Host: $ip \n
- Porta: $port \n
- Diretório host: $dir_send \n"
- if ! dialog --title "CONFIRMA OS DADOS?" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "$text" \
- 0 0
- then
- repete_form # Aperto nao? então chamamos o formulário de novo.
- fi
- }
- repete_form # Chamada função para formulário
- choose_the_tag=$(
- dialog --stdout \
- --title "ESCOLHA AS OPÇÕES!" \
- --backtitle "$back" \
- --checklist "" \
- 0 0 0 \
- "-l" "Limitar o tamanho da banda" off \
- "-r" "Copie recursivamente diretórios inteiros." off \
- "-p" "Preserva as horas de modificação, os tempos de acesso e os modos do arquivo original." off \
- )
- while :; do
- if echo "$choose_the_tag" | grep -q -o "\-l"; then
- local text="Informe em quanto deseja limitar o tamanho da banda em Kbits
- Somente Números! 100000 kbits = 1 mb"
- kbits=$(
- dialog --stdout \
- --title "INFORME" \
- --backtitle "$back" \
- --inputbox "$text" \
- 0 0
- )
- # Alterando a Váriavel para receber valor do kbits.
- echo "$choose_the_tag" > "$log_tags"
- choose_the_tag=$(sed "s/-l/-l $kbits/" "$log_tags")
- fi
- # Verificando se váriavel 'kbits' é númerica.
- numeric(){ echo "$@" | grep -q -v "[^0-9]"; }
- if ! numeric "$kbits"; then
- dialog --title "OPS." \
- --backtitle "$back" \
- --msgbox "Favor informe uma entrada NÚMERICA!" \
- 5 50
- else
- break
- fi
- done
- # Bloco para escolher diretório de origem
- while :; do
- dir_if_backup=$(
- dialog --stdout \
- --title "SELECIONE O DIRETÓRIO/ARQUIVO DE 'ORIGEM'" \
- --backtitle "$back" \
- --cancel-label "Voltar" \
- --dselect "/" \
- 8 80 )
- if [[ "$?" -ne "0" ]]; then
- dialog --title "RETORNANDO" \
- --backtitle "$back" \
- --sleep 2 \
- --infobox "\nOK, retornando ao menu principal..." \
- 5 40
- main # Retornando ao menu principal
- fi
-
- if ! dialog --title "CONFIRMA?" \
- --backtitle "$back" \
- --yes-label "Sim" \
- --no-label "Não" \
- --yesno "Confirma o diretório de 'ORIGEM': $dir_if_backup" \
- 6 80
- then
- dialog --title "VOLTANDO" \
- --backtitle "$back" \
- --msgbox "Vamos retornar então." \
- 5 40
- continue
- fi
- # Usuário tem permissão de Leitura e escrita no diretorio?
- # Se tiver para o loop e continua, se não volta.
- if [[ ! -w "$dir_if_backup" ]] && [[ ! -r "$dir_if_backup" ]]; then
- dialog --title "SEM PERMISSÃO!" \
- --backtitle "$back" \
- --msgbox \
- "\nSem permissões neste diretório...\n
- Escolha outro diretório, ou dê as devidas permissões para este diretório." \
- 8 80
- else
- break # Digitou sim o loop para e continua :)
- fi
- done # Fecha loop principal
-
- # Enviando arquivos para o Destino.
- dialog --title "Digite O SEU PASSWORD!" \
- --sleep 1 \
- --infobox "Informe seu password para dar continuidade!" \
- 0 0
- if execute_scp 2>"$log"; then
- dialog --title "CONCLUIDO" \
- --back "$back" \
- --msgbox "Concluido"
- 0 0
- else
- sed -i 's/scp/dunee/g' "$log"
- dialog --title "OPS." \
- --backtitle "$back" \
- --exit-label "Voltar" \
- --textbox "$log" \
- 0 0
- [[ -e "$log" ]] && rm "$log" # Existe? então remove arquivo de log em /tmp/
- fi
- ;; # Fecha opção case enviar
-
- # Se for RECEBER cai aqui!|
- "Receber")
- remote_main
-
- if execute_scp 2>"$log"; then
- dialog --title "CONCLUIDO" \
- --back "$back" \
- --msgbox "Concluido"
- 0 0
- else
- sed -i 's/scp/dunee/g' "$log"
- dialog --title "OPS." \
- --backtitle "$back" \
- --exit-label "Voltar" \
- --textbox "$log" \
- 0 0
- [[ -e "$log" ]] && rm "$log" # Existe? então remove arquivo de log em /tmp/
- fi
- ;; # Fecha opção case enviar
-
- esac # Fecha case 'send_or_receive' PRINCIPAL
- }
- #########################################################|
- ################### INICIO ##############################|
- #########################################################|
- # Tela de boas vindas.
- dialog --title "$name" \
- --backtitle "$back" \
- --ok-label "Avançar" \
- --msgbox \
- "\nSeja bem vindo ao $name.\n
- Nunca foi tão fácil fazer seus backups!\n
- Caso você precise de ajuda entre na opção <AJUDA> para saber mais sobre
- o $name" \
- 10 80
- # Menu principal,amarrado.
- main(){
- while :; do
- menu=$(dialog --stdout \
- --title "$name" \
- --backtitle "$back" \
- --help-button \
- --help-label "Ajuda" \
- --cancel-label "Cancelar" \
- --menu \
- "USE O <DIRECIONAL> PARA SE LOCOMOVER, <ESPAÇO> PARA SELECIONAR." \
- 0 0 0 \
- "Básico" "Modo básico para um simples backup, (COMPACTADO)" \
- "Remoto" "Envie/receba seus backup remotamente (SIMPLES)" \
- "Conexão" "Testa se a conectividade com a internet." \
- "Avançado" "Para um backup completo" )
- #Verificando status de saida dos botões.
- case $? in
- "$help_button")
- dialog --title "MÓDULOS PRINCIPAIS" \
- --backtitle "$back" \
- --exit-label "Voltar" \
- --textbox "$directory_root/menu-principal.txt" \
- 20 100 ;;
- *)
- status ;; # status chamada função status, botões globais (1, 255)
- esac
- ##################################################################################
- # Verificando qual opção do menu o usuário selecionou (Básico, Remoto, Avançado) #
- ##################################################################################
- case $menu in
-
- Básico) basic_mod ;;
-
-
- Remoto) remote ;;
-
-
- Conexão)
- #Conferindo se tem internet
- local text="\nConferindo se há conexão com a internet."
- dialog --title "TESTE..." \
- --backtitle "$back" \
- --infobox "$text" \
- 5 60
- if ! wget -q --spider www.google.com; then
- local text="\nParece que você não há conexão com a internet.
- Restabeleça uma conexão e retorne.\n\n
- Caso você não tem o X disponivel, rode o comando logado como root:\n
- # ifconfig -a\n
- Veja a listagem e encontre a flag da sua rede...\n\n
- Para conexões a cabo normalmente a tag inicia com 'eth'.\n
- Para Wifi a tag inicia com 'wlan'.\n
- Para dispositivo Android roteado 'usb'\n\n
- Para estabelecer uma conexão você pode utilizar os comandos:
- 'dhcpcd opção flag_aqui' ou 'dhclient flag_aqui'"
- dialog --title "OPS!" \
- --backtitle "$back" \
- --msgbox "$text" \
- 18 100
- main # Retornando ao menu principal
- else
- dialog --title "OK!" \
- --backtitle "$back" \
- --ok-label "Prossiga" \
- --msgbox "\nConexão Estabelecida." \
- 7 35
- fi
- ;;
-
- Avançado)
- text="\nAguarde!\n
- Está opção ainda não está disponivel no ${name}..."
- dialog --title "Em criação." \
- --backtitle "$back" \
- --msgbox "$text" \
- 8 60
- ;;
- esac ###### case menu
- done ###### fecha loop while pricipal
- } ###### Fecha função main
- main # Chamada função main.
|