Backup Máquina do Tempo com Rsync

Publicado por Fabio Lima (última atualização em 14/04/2015)

[ Hits: 5.899 ]

Homepage: https://twitter.com/fabiolimace

Download 6194.rsync-backup_ARQUIVOS.zip

Download rsync-backup.tar.gz (versão 2)




Este script serve para fazer backups periódicos no estilo máquina do tempo (Time Machine OSX). Ele é executado a partir de uma máquina central. Essa máquina acessa outras máquinas via rsync + ssh.

Por utilizar hard-links, os backups não crescem muito.

Caso se deseje a cópia exata de um "repositório" num dia específico, basta procurar a pasta correspondente, desde que o backup tenha sido feito nesse dia.

Anexei um arquivo compactado contendo todos os arquivos necessários para rodar o script, inclusive um tutorial em PDF.

  



Versões atualizadas deste script

Versão 2 - Enviado por Fabio Lima em 09/04/2015

Changelog: Acrescentei informações no PDF que acompanha o script.

Download rsync-backup.tar.gz


Esconder código-fonte

#!/usr/bin/env bash
#
# rsync-backup
# Makes backups of local and remote hosts using rsync.
# 
# Author: Fabio Lima
# Date: 2015-03-28
# 

# Checks if the three parameters are supplied
if [ -n "${1}" -a -n "${2}" -a -n "${3}" ];
then
   SRC_HOST="${1}";
   SRC_REPO="${2}";
   SRC_DIR="${3}";
else
   echo -e "HOW TO USE:\nrsync-backup HOST REPOSITORY PATH";
   exit 1;
fi;

# Default backup directory. See example:
# RSYNC_DIR="/mnt/backup/Automático/rsync-backup";
RSYNC_DIR="/PATH/TO/rsync-backup";

# Default backup user.
RSYNC_USER="rsync-backup";

# Special directories names.
# You can change it if you want.
LAST_LABEL="ultimo";
FULL_LABEL="completo";
REMOVED_LABEL="removido";

DATE=$(date "+%Y-%m-%d");
TIME=$(date "+%Hh%M");

HOST_DIR="${RSYNC_DIR}/${SRC_HOST}";
REPO_DIR="${HOST_DIR}/${SRC_REPO}";
DEST_DIR="${REPO_DIR}/${DATE}";

DEST_FULL_DIR="${DEST_DIR}/${FULL_LABEL}";
DEST_REMOVED_DIR="${DEST_DIR}/${REMOVED_LABEL}-${TIME}";

LAST_DEST_DIR="${REPO_DIR}/${LAST_LABEL}";
LAST_FULL_DIR="${LAST_DEST_DIR}/${FULL_LABEL}";

RSYNC_LOG="${REPO_DIR}/rsync.log";
SCRIPT_LOG="${REPO_DIR}/rsync-backup.log";

# Checks if the source host is the local host.
# If it is a remote host, rsync uses SSH authentication.
if [ "${SRC_HOST}" = "$(hostname)" ];
then
   RSYNC_SSH_LOGIN="";
else
   RSYNC_SSH_LOGIN="${RSYNC_USER}@${SRC_HOST}:";
fi;

# Changes multiple spaces and tabs for single spaces
function fn_single_spaced {
   STR="${1}";
   
   echo "${STR}" | tr -s '\t ' '  ';
}

# Makes a directory if it doesnt exist
function fn_make_dir {
   NEW_DIR="${1}";

   MKDIR_COMMAND=$(fn_single_spaced \
   "mkdir -p \"${NEW_DIR}\";"); 

   if [ ! -d "${NEW_DIR}" ];
   then   
      echo ${MKDIR_COMMAND};
      bash -c "${MKDIR_COMMAND}";
   fi;
}

# Copies files using hard links
function fn_link_copy {
   COPY_SRC="${1}";
   COPY_DEST="${2}";

   COPY_COMMAND=$(fn_single_spaced \
   "cp --archive --link \"${COPY_SRC}/\"* \"${COPY_DEST}\";");

       if [ -n "${COPY_SRC}" -a -d "${COPY_SRC}" ];
       then
      echo ${COPY_COMMAND} &>> "${SCRIPT_LOG}";
      bash -c "${COPY_COMMAND}" &>> "${SCRIPT_LOG}";
       fi;
}

# Removes empty directories.
function fn_remove_empty_dirs {
   DIR="${1}";

   FIND_COMMAND="find \"${DIR}\" -type d -empty -delete;";
   RMDIR_COMMAND="rmdir --ignore-fail-on-non-empty \"${DIR}\";";

   if [ -n "${DIR}" -a -d "${DIR}" ];
   then
      echo ${FIND_COMMAND}  &>> "${SCRIPT_LOG}"; 
      bash -c "${FIND_COMMAND}" &>> "${SCRIPT_LOG}";
      
      #echo ${RMDIR_COMMAND} # &>> "${SCRIPT_LOG}"; 
      #bash -c "${RMDIR_COMMAND}"# &>> "${SCRIPT_LOG}";
   fi;
}

# Checks if there are changes to be transfered
function fn_has_changes {

   RSYNC_COMMAND=$(fn_single_spaced \
   "rsync --dry-run --archive --relative --itemize-changes \
   --cvs-exclude --exclude=\".*\" --exclude=\".*/\" \
   ${RSYNC_SSH_LOGIN}\"${SRC_DIR}\" \
   \"${LAST_FULL_DIR}\";");
   
   if [ -d "${LAST_FULL_DIR}" ];
   then
      echo ${RSYNC_COMMAND} &>> "${SCRIPT_LOG}";
      RESULT=$(bash -c "${RSYNC_COMMAND}" );


      if [ -n "${RESULT}" ];
      then
         echo 1;
      else 
         echo 0;
      fi;
   else 
      echo 1;
   fi;
}

# Core function of this script
function fn_rsync_backup {

   RSYNC_COMMAND=$(fn_single_spaced \
   "rsync --archive --relative --itemize-changes \
   --cvs-exclude --exclude=\".*\" --exclude=\".*/\" \
   --compress --verbose --delete --backup \
   --log-file=\"${RSYNC_LOG}\" \
   --backup-dir=\"${DEST_REMOVED_DIR}\" \
   ${RSYNC_SSH_LOGIN}\"${SRC_DIR}\" \
   \"${DEST_FULL_DIR}\";");

   SYMLINK_COMMAND=$(fn_single_spaced \
   "ln --symbolic --relative --force --no-dereference \
   \"${DEST_DIR}\" \"${LAST_DEST_DIR}\";");

   # Create destination directories
   fn_make_dir "${DEST_FULL_DIR}" &>> "${SCRIPT_LOG}";
   fn_make_dir "${DEST_REMOVED_DIR}" &>> "${SCRIPT_LOG}";

   # Hard link copy last full directory to new full directory
   fn_link_copy "${LAST_FULL_DIR}" "${DEST_FULL_DIR}";

   # Transfer changes using rsync
   echo ${RSYNC_COMMAND} &>> "${SCRIPT_LOG}";
   bash -c "${RSYNC_COMMAND}" &>> "${SCRIPT_LOG}";

   # Make simbolic link to new full directory 
   echo ${SYMLINK_COMMAND} &>> "${SCRIPT_LOG}";
   bash -c "${SYMLINK_COMMAND}" &>> "${SCRIPT_LOG}";

   # Remove empty directories
   fn_remove_empty_dirs "${DEST_REMOVED_DIR}";

}

function fn_main {

   MK_REPO=$(fn_make_dir "${REPO_DIR}");

   START_DATE=$(date "+%Y-%m-%d %H:%M:%S");
   echo "---------------------------------" >> "${SCRIPT_LOG}";
   echo START SCRIPT: ${START_DATE} >> "${SCRIPT_LOG}";
   echo "---------------------------------" >> "${SCRIPT_LOG}";
   
   if [ -n "${REPO_DIR}" ];
   then
      echo "${MK_REPO}" >> "${SCRIPT_LOG}";
   fi;

   # Starts transfer only if there are chenges
   if [ "$(fn_has_changes)" -eq 1 ];
   then
      fn_rsync_backup;
   else
      echo "No changes." >> "${SCRIPT_LOG}";
   fi; 

   END_DATE=$(date "+%Y-%m-%d %H:%M:%S");
   echo "---------------------------------" >> "${SCRIPT_LOG}";
   echo END SCRIPT: ${END_DATE} >> "${SCRIPT_LOG}";
   echo "---------------------------------" >> "${SCRIPT_LOG}";
   echo -e "\n\n" >> "${SCRIPT_LOG}";
}

fn_main;

Scripts recomendados

Script Backup com Log e envio por Email

Enviando e-mail localmente após o backup para monitoramento

Backup, compactação, verificação e transferência de arquivos

Backup de logs do sistema

Backup XML Pfsense


  

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