Shell script para backup: nova versão

Outro dia atualizei o que faltava no meu shell script para fazer backup usando o rsync.

Adicionei o wakeonlan para ligar a máquina remotamente (necessário descobrir o HW address da sua máquina de destino e se certificar de que é possível ligá-la remotamente — possível que tenha que ativar essa opção na BIOS), dei uma arrumadinha, incluí a opção de excluir arquivos e pastas do backup (ver abaixo) e adicionei num cron job para fazer um backup diário. Além disso, o script desliga a máquina depois do fim do backup. Aqui está:

#!/bin/bash

# Script para backup via SSH usando o rsync
# Versão 0.8 - 2009/09/05

# # # # # # Configuração # # # # # #

# Mude os parâmetros abaixo, referentes ao seu sistema

# Arquivo log
LOG=/home/user0/.backup`date +%Y-%m-%d`.log

# IP ou hostname da máquina de destino
DESTINO=destino.local

# Usuário no destino
USR=user1

# Diretório de destino
DIR=/home/user1/Backup/

# Diretório de origem
SRC=/home/user0

# Arquivo com lista de arquivos e diretórios
# que não serão incluídos no backup
EXCLUIR=/home/user0/.rsync/exclude

# HW address
HW=00:ee:dd:cc:bb:aa

# # # # # # Configuração # # # # # #

# # # # # # #  Funções # # # # # # #

function ligada
{
# Checar se a máquina de destino está ligada
echo -e "Checando se $DESTINO está ligada..."
/bin/ping -c 1 -W 2 $DESTINO > /dev/null
if [ "$?" -ne 0 ]; then
return 1
else
return 0
fi
}

function run_backup
{
HORA_INI=`date +%s`
echo -e `date +%c` >> $LOG
echo -e "\n$DESTINO ligado!" >> $LOG
echo -e "Iniciando o backup...\n" >> $LOG
rsync -ah --delete --stats --progress --log-file=$LOG --exclude-from=$EXCLUIR -e ssh $SRC $USR@$DESTINO:$DIR
HORA_FIM=`date +%s`
TEMPO=`expr $HORA_FIM - $HORA_INI`
echo -e "\nBackup finalizado com sucesso!" >> $LOG
echo -e "Duração: $TEMPO s\n" >> $LOG
echo -e "--- // ---\n" >> $LOG
echo -e "\nBackup finalizado com sucesso!"
echo -e "Duração: $TEMPO s\n"
echo -e "Consulte o log da operação em $LOG.\n"
}

# # # # # # # Funções  # # # # # # #

# # # # # # # Programa # # # # # # #

# Checar se a máquina de destino está ligada
ligada
if [ "$?" -eq "1" ]; then
echo -e "\n$DESTINO desligado. Tentando acordá-lo..."
wakeonlan $HW
echo -e "\nPacote mágico enviado. Aguarde."
sleep 70
ligada
if [ "$?" = "1" ]; then
echo -e `date +%c` >> $LOG
echo -e "\n$DESTINO desligado." >> $LOG
echo -e "Backup não realizado\n" >> $LOG
echo -e "--- // ---\n" >> $LOG
echo -e "\n$DESTINO desligado."
echo -e "Backup não realizado.\n"
else
echo -e "\n$DESTINO ligado! Começando o backup..."
run_backup
fi
else
echo -e "\n$DESTINO ligado! Começando o backup..."
run_backup
fi

echo -e "Desligando o $DESTINO..."
ssh $USR@$DESTINO 'sudo halt'
echo -e "Pronto. Tchau!"

# # # # # # # Programa # # # # # # #

# # # # # # # Afazeres # # # # # # #
#
#	- Criar alça para quando a transferência falhar (e.g.,falta de espaço)

Meu arquivo exclude, com a lista de arquivos e pastas que não serão incluídas no backup ficou assim:

.thumbnails/
Picasa.ini
Thumbs.db
.local/share/Trash/
.cache/
.gvfs/

Shell script para backup usando rsync e ssh em DHCP no Ubuntu

[Fiz uma versão nova, mais completa, deste script. Confira aqui.]

No meu computador mantenho apenas arquivos essenciais para o trabalho da semana/mês e vou estocando tudo em discos rígidos externos progressivamente. Contudo, como eles são meio desorganizados, queria um jeito prático de fazer backup completo dos arquivos diários de trabalho.

A solução foi criar um script em shell (bash) que fizesse uma cópia exata do meu computador para outra máquina conectada na rede local.

Depois de uma rápida pesquisa vi que o rsync era a ferramenta que estava procurando para o trabalho. Não é preciso muito para conseguir fazer o backup com o rsync, basta usar o seguinte comando (cheque a documentação para entender os argumentos):

rsync -ah --delete -e ssh /home/user1 user2@IPouHostname:/home/user2/Backup/
#nota de precaução: o --delete faz com que os arquivos no destino sejam deletados, caso estejam ausentes na origem

No entanto, foi preciso configurar algumas coisas para que tudo corresse bem nas duas máquinas rodando Ubuntu.

Como minha rede local é DHCP as máquinas não tem um IP estático. Queria rodar o script sem precisar saber o IP do destino usando apenas o hostname (nome da máquina na rede). Quando tentei conectar via ssh usando o hostname original não consegui. Para funcionar é necessário simplesmente mudar o hostname da máquina de destino para hostname.local. Siga estas instruções resumidas abaixo:

  1. Abra o arquivo /etc/hosts com um editor de texto pelo terminal

    sudo vim /etc/hosts

  2. Mude a linha

    127.0.1.1 hostname

    para

    127.0.1.1 hostname.local

  3. Salve o arquivo e abra o arquivo /etc/hostname com

    sudo vim /etc/hostname

  4. Mude o hostname para hostname.local e salve
  5. Reinicie a máquina ou execute:
    1. sudo /etc/init.d/hostname.sh stop
    2. sudo /etc/init.d/hostname.sh start
    3. sudo /etc/init.d/network restart

Com isso foi possível conectar via ssh sem precisar saber o IP, apenas com o hostname. Outra pendenguinha é que o ssh precisa da senha de usuário da máquina de destino para se conectar. Pra evitar isso e conseguir fazer o login remotamente sem precisar digitar a senha siga estes passos (isso permite com que você possa iniciar o backup sem precisar estar por perto, por exemplo deixar agendado para rodar o script 1 vez por semana).

Com isso resolvido abra o script abaixo num editor de texto, edite os detalhes de configuração, salve e execute o script num terminal. Para executar torne o arquivo executável com o comando

chmod 755 backup.sh

e execute com

./backup.sh

Tentei fazer com que meu computador ligasse remotamente (para que nem precisasse ligar a máquina de destino pra fazer backup – o script a ligaria remotamente), mas não consegui. Tem instruções sobre o wakeonlan aqui.

O script abaixo basicamente:

  • Checa se a máquina de destino está ligada (se estiver desligada ele avisa, põe no log e fecha)
  • Se estiver ligada ele executa o rsync (o –delete-before deleta os arquivos do destino antes de copiar os arquivos novos; útil se não houver muito espaço no disco do destino – o padrão é –delete que vai deletando e copiando progressivamente)
  • O terminal mostra todas as operações e calcula a duração do backup. Tudo isso fica registrado num arquivo log

Obviamente sugestões são muito bem vindas! Segue então o script:

#!/bin/bash

# Script para backup via SSH usando o rsync
# Versão 0.1

## Configuração!!! ##
# Mude os parâmetros abaixo, referentes ao seu sistema

# Arquivo log
LOG=/home/user0/.backup`date +%Y-%m-%d`.log

# Destino
# IP ou hostname da máquina de destino
DESTINO=destino.local

# Usuário no destino
USR=user1

# Diretório de destino
DIR=/home/user1/Backup/

# Origem
# Diretório de origem
SRC=/home/user0

## Fim das Configurações!!! ##

# Checar se a máquina de destino está ligada
/bin/ping -c 1 -W 2 $DESTINO > /dev/null
if [ "$?" -ne 0 ];
then
   echo -e `date +%c` >> $LOG
   echo -e "\n$DESTINO desligado." >> $LOG
   echo -e "Backup não realizado\n" >> $LOG
   echo -e "--- // ---\n" >> $LOG
   echo -e "\n$DESTINO desligado."
   echo -e "Backup não realizado.\n"
else
   HORA_INI=`date +%s`
   echo -e `date +%c` >> $LOG
   echo -e "\n$DESTINO ligado!" >> $LOG
   echo -e "Iniciando o backup...\n" >> $LOG
   rsync -ah --delete --stats --progress --log-file=$LOG -e ssh $SRC $USR@$DESTINO:$DIR
   HORA_FIM=`date +%s`
   TEMPO=`expr $HORA_FIM - $HORA_INI`
   echo -e "\nBackup finalizado com sucesso!" >> $LOG
   echo -e "Duração: $TEMPO s\n" >> $LOG
   echo -e "--- // ---\n" >> $LOG
   echo -e "\nBackup finalizado com sucesso!"
   echo -e "Duração: $TEMPO s\n"
   echo -e "Consulte o log da operação em $LOG.\n"
fi

# Afazeres

#	- Incluir em cron job!
#	- Definir como lidar com o arquivo.log (deletar, arquivar, deixar...)
#	- Incluir wakeonlan para ligar o computador se estiver desligado
#	- Desligar máquina de destino após o término do backup
#	- Criar alça para quando a transferência falhar (e.g.,falta de espaço)

Mestre em LaTeX

Mestre em LaTeX

O Mestre em LaTeX tem como objetivo facilitar a vida de quem está prestes a escrever sua dissertação de mestrado ou tese de doutorado em português. Ele é um modelo de dissertação que contém informações básicas para iniciantes em LaTeX, além de incluir uma série de pacotes úteis para escrever sua dissertação/tese eficientemente na língua portuguesa.

Confira a primeira versão aqui.

O projeto está hospedado no endereço http://code.google.com/p/mestre-em-latex/ onde estou acrescentando informações no wiki e você pode reportar problemas. Além disso, a versão mais recente está disponível via Mercurial.

Quick Set Scale, macro para o ImageJ!

Esse tópico é um pouco velho, pois acabei ficando sem tempo pra publicar!

Como vocês já devem ter lido por aqui, gosto e uso bastante o ImageJ, um software de processamento de imagens. Uma das tarefas que faço frequentemente é medir “coisas” que estudo. Essas coisas podem ser células, embriões, larvas, seres do plâncton, ou bolachas-do mar adultas.

Para fazer as medições você precisa calibrar a foto informando ao programa qual é o tamanho (em cm, mm, µm, etc…) de cada pixel. Por exemplo, se cada pixel equivale a 1cm e a célula que fotografei tiver 800 pixels de diâmetro, o diâmetro real desta célula é de 800cm (8 metros!).

escala

Para descobrir que valor usar é simples, tire uma foto de uma escala numérica (uma régua, ou algo que você saiba o tamanho com precisão) , e lembre-se de não alterar o zoom e posição da câmera ou aumento do microscópio quando bater suas fotos. Se precisar mudar, bata outra foto da escala com a nova configuração!

Como eu tenho imagens com diferentes aumentos, mas sempre tirados com a mesma câmera, objetivas, microscópio e lupa, fiz uma pequena macro para facilitar minha vida. A macro simplesmente calibra a foto de acordo com valores pré-determinados pelo usuário (meus equipamentos, um microscópio e uma lupa). Pra usar você precisa descobrir quais valores você deve colocar! Não use os valores que estão no código original! Tentei deixar bem fácil para alterar esses valores e adicionar outros equipamentos.

Pra usar é só salvar o código como um arquivo .txt, colocar na pasta ImageJ/macros/toolsets e reiniciar o ImageJ. Esse código foi melhorado pelo Wayne Rasband, que criou o ImageJ, quem quiser ver a versão anterior tem aqui (não use a versão anterior… é só para quem tiver curiosidade em comparar as mudanças). O Quick Set Scale foi incorporado na versão 1.39g do ImageJ!

Depois coloco umas fotos… 🙂

// Quick Set Scale v0.99 - 15/10/2007
// Copyleft - Bruno C. Vellutini
// Macro specific for Compound Microscope Zeiss Axioplan2 and Stereoscope Zeiss Stemi SV11 APO
// with photos taken with a Nikon Coolpix 4500 camera (max zoom)
// If you are using this macro you need to input your own values
// specific for your scope and camera set up

var global = false;

macro "Unused Tool - " {}

macro "Quick Set Scale Action Tool - C037L1cfcL1a1eLfafeL8b8dL5b5dLbbbdT0707qT4707uT8707iTa707cTe707k" {

Dialog.create("Quick Set Scale");
// Write the name of the equipments you want to quickly set scale in the array below
Dialog.addChoice("Equipment:", newArray("Microscopio Zeiss Axioplan2", "Lupa Zeiss Stemi SV11 APO"));
Dialog.show();
equip = Dialog.getChoice();

// Options for Axioplan2
if (equip=="Microscopio Zeiss Axioplan2") {
// Write the magnifications available for your equipment
magnifications = newArray("2.5x", "10x", "20x", "40x", "100x");
scales = newArray("2.0450",  "0.5277", "0.2571", "0.1333", "0.05255");
setScale("Zeiss Axioplan2", magnifications, scales);
}

// Options for Stereoscope.
if (equip=="Lupa Zeiss Stemi SV11 APO") {
magnifications = newArray("0.6x", "0.8x", "1.0x", "1.2x", "1.6x", "2.0x", "2.5x", "3.2x", "4.0x", "5.0x", "6.6x");
scales = newArray("5.788712012", "4.246284501",  "3.318620781", "2.631509697", "2.087682672",
"1.680672269", "1.353784505",  "1.06835324", "0.850340136", "0.661371287",  "0.506072874");
setScale("Lupa Zeiss Stemi SV11 APO", magnifications, scales);
}
}

function setScale(name, mag, scale) {
Dialog.create(name);
Dialog.addChoice("Objective:", mag);
Dialog.addCheckbox("Global Scale", global);
Dialog.show();
magnification = Dialog.getChoice();
global = Dialog.getCheckbox();
options = " distance=1 pixel=1 unit=micron known=";
for (i=0; i
if (magnification==mag[i]) options = options + scale[i];
}
if (global) options = options + " global";
run("Set Scale...", options);
}