Skip to content

Instantly share code, notes, and snippets.

@viniciusgonmelo
Last active June 13, 2023 04:09
Show Gist options
  • Save viniciusgonmelo/3ae694deb25889f09eab8f7c856e1af4 to your computer and use it in GitHub Desktop.
Save viniciusgonmelo/3ae694deb25889f09eab8f7c856e1af4 to your computer and use it in GitHub Desktop.
Backup local do $HOME de usuários do sistema
#!/usr/bin/env perl
# Script para realizar backup do diretório home de um ou mais usuários utilizando rsync e tar.
# Exemplo de uso: ./backup-home usuario_1 usuario_2
# Será criado um novo backup .tgz para cada usuário informado em $backup_dir.
use 5.010;
use strict;
use warnings;
use DateTime;
use Log::Log4perl qw(:easy);
use File::Basename;
use Carp;
use File::Path qw( make_path );
my $script_name = basename $0;
my $script_dir = dirname(__FILE__);
# Diretório para backup
my $backup_dir = '/media/backup';
# Configuração de log
my $log_file = '/var/log/' . $script_name . '.log';
my $conf = <<"EOF";
log4perl.rootLogger = DEBUG, file, screen
log4perl.appender.screen = Log::Log4perl::Appender::Screen
log4perl.appender.screen.stderr = 0
log4perl.appender.screen.layout = PatternLayout
log4perl.appender.screen.layout.ConversionPattern = %d %m%n
log4perl.appender.file = Log::Log4perl::Appender::File
log4perl.appender.file.filename = $log_file
log4perl.appender.file.mode = append
log4perl.appender.file.layout = PatternLayout
log4perl.appender.file.layout.ConversionPattern = %d %m%n
EOF
Log::Log4perl::init( \$conf );
@ARGV or croak 'Uso: ./backup-home usuário_1 usuário_2';
my @users;
# Processa argumentos de linha de comando
foreach my $user (@ARGV){
push(@users, $user);
}
INFO 'Início do backup.';
foreach my $user (@users) {
my $user_home = ( getpwnam $user )[7] or do {
ERROR "Usuário $user não existe.";
next;
};
if ( ! -d $user_home ) {
# Exibe mensagem de erro se o diretório home do usuário não existe
ERROR "Diretório home não existe para o usuário $user.";
next;
}
# Diretório de backup para o usuário
my $user_backup_dir = "$backup_dir/home-backup/$user";
make_path $user_backup_dir unless -d $user_backup_dir;
# Remove todos os backups exceto os 10 mais recentes
my @files = sort { -M $a <=> -M $b } glob "$user_backup_dir/*";
if ( scalar(@files) > 10 ) {
splice @files, 0, -10;
unlink @files;
}
# Diretório temporário para armazenar backup antes de compactar
my $user_backup_tmp_dir = "/var/tmp/backup-home-$user";
mkdir $user_backup_tmp_dir unless -d $user_backup_tmp_dir;
# Cria nome do arquivo de backup com base na data atual
my $now = DateTime->now;
my $tgz = "$user_backup_dir/" . $now->strftime('%Y%m%d') . "_home-$user.tgz";
INFO "Início do backup de $user.";
# Executa comando rsync para copiar arquivos para o diretório temporário
my $cmd_rsync
= "rsync -aAXzv --delete --links --exclude swapfile --exclude lost+found --exclude .cache --exclude /backup --exclude /var/tmp --exclude /tmp --stats \"$user_home\" \"$user_backup_tmp_dir\"";
my $rsync_output = `$cmd_rsync 2>&1`;
my $rsync_status = $? >> 8;
if ( $rsync_status != 0 ) {
# Exibe mensagem de erro se o comando rsync falhar
ERROR "Erro ao executar comando rsync:\n$rsync_output";
next;
}
# Executa comando tar para compactar o diretório temporário
my $cmd_tar = "tar --overwrite -czvf \"$tgz\" \"$user_backup_tmp_dir\"";
my $tar_output = `$cmd_tar 2>&1`;
my $tar_status = $? >> 8;
if ( $tar_status != 0 ) {
# Exibe mensagem de erro se o comando tar falhar
ERROR "Erro ao executar comando tar:\n$tar_output";
next;
}
# Remove diretório temporário
system("rm -rf \"$user_backup_tmp_dir\"") == 0 or do {
ERROR "Erro ao remover diretório temporário $user_backup_tmp_dir: $!";
};
INFO "Backup de $user concluído.";
}
INFO 'Backup completo.';
exit 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment