Agendamento de tarefas no crontab

O crontab é um programa do Unix que edita o arquivo onde são especificados os comandos a serem executados e a hora e dia de execução pelo cron. O cron é o daemon responsável por executar os comandos agendados e recorrentes (todo dia, toda semana, etc). O cron leva em conta as alterações de horário como o horário de verão: quando é retirada uma hora, as ações são executadas logo após a alteração de horário; se acrescentar uma hora, somente são realizadas uma única vez.

Cada usuário tem o seu crontab, que pode ser editado (opção “-e”) ou listado (opção “-l”). Os arquivos com as instruções são nomeados por usuário e estão localizados em “/var/spool/cron/crontabs/”. Veja sua sintaxe para, a cada 5 minutos, executar a atualização do horário:

crontab-explicacao

Veja alguns exemplos:

# Desligar computador dia 23-11-2013 (sábado) às 7h
0 7 23 11 6 /sbin/shutdown -h now
# Executar script a cada 10 minutos às segundas e quartas (se fosse de SEG a QUA, seria 1-3)
00-59/10 * * * 1,3 /home/user/script.sh  > /home/user/temp.log 2>&1
# Executa script python na inicialização e redireciona saída padrão para background
@reboot python /home/user/script.py 2> /home/user/temp.log &
# Executa script python na inicialização e redireciona saída padrão para tty1
@reboot /usr/bin/python /home/user/script.py 1> /dev/tty1 2> /home/user/temp.log

O asterisco indica todas as opções possíveis. Utilizar uma barra indica que deve ser executado repetidamente a cada intervalo de tempo. Para mais de um parâmetro, separar por vírgula dias e horários distintos e por traço os intervalos de tempo. Em vez dos parâmetros de data e horário, é possível usar “@reboot” para iniciar script junto com a inicialização do sistema operacional.

É recomendado usar redirecionamento das saídas -o que não é o caso do 1º exemplo. No 2º exemplo, a saída padrão e a de erros estão encaminhadas para serem salvas no arquivo “temp.log”. Nos seguintes, somente a saída de erros é redirecionada para esse arquivo, sendo que a saída padrão vai para o background e para a tela 1 (tty1), respectivamente.

Geralmente, o editor padrão do crontab é o nano. Caso não seja e queira utilizá-lo, use o seguinte comando:

bash -c "export VISUAL=/bin/nano; crontab -e"

Nesse caso, supõe-se que o nano esteja no diretório “/bin” e que a variável “$SHELL” seja diferente de “/bin/bash” – para verificar se é, utilize o comando “echo $SHELL”. Caso já esteja com o bash, basta digitar diretamente o que está dentro das aspas.

Sempre insira o caminho completo em tudo (não só no crontab, mas também dentro dos scripts) para ter a certeza que será executado sempre da mesma forma independente do diretório que esteja.

Um truque é definir o diretório do script em uma variável logo no início da rotina. Como o crontab considera a home do usuário como seu diretório corrente, o comando “pwd” não retorna o diretório do script. Veja essa sugestão para imprimir o diretório que está o script em uma variável, que funciona tanto executando através do crontab como diretamente na linha de comando:

DIR=$(readlink -f -- $0 | awk -F "/" 'sub(FS $NF,x)')

O duplo traço foi inserido para funcionar no BSD, que estava dando um erro estranho. O $0 é o argumento 0, que corresponde ao caminho do arquivo sendo executado – mas se eu fizesse “DIR=$0”, seria guardado algo como “./script.sh” e não o caminho completo. Como a saída do comando “readlink” inclui o interpretador (bash, tcsh, etc), deve-se separar a saída desse comando pelas barras e excluir o último termo (NF).

Esse comando é útil para programar backups de arquivos importantes (principalmente copiando para outros computadores). Segue um exemplo de script para fazer o backup com a linha a ser incluída no crontab comentada. Os redirecionamentos de saída são uma sugestão para gravar as mensagens (bkp.log1) e eventuais erros (bkp.log2):

#!/bin/bash
# Backup
# 00 22 * * * /home/user/bkp.sh 1> /home/user/bkp.log1 2> /home/user/bkp.log2

# Definindo destino de backup
destino='user@maq_bkp:/dados/bkp'
# Copiar/Atualizar configurações de acesso ssh
sshpass -p "SENHA" cp ~/.ssh/config $destino
# Copiar/Atualizar diretório remotamente e sem ter que digitar senha
sshpass -p "SENHA" rsync -azv --progress --delete DIRETORIO_1 $destino
# Copiar/Atualizar somente arquivos, sem diretórios
sshpass -p "SENHA" rsync -azv --progress --delete --exclude "*/" DIRETORIO_2 $destino
# Copiar/Atualizar somente arquivos com a extensão informada
sshpass -p "SENHA" rsync -azv --progress --delete --include '*.pro' --exclude '*' DIRETORIO_3 $destino

As atividades do cron podem ser paradas através do comando “/etc/init.d/cron stop” – para reiniciar, utilizar “start”.

Os trabalhos do Cron precisam de operação silenciosa; se um comando gerar saída, você receberá um e-mail do cron com a saída do comando. Então, para baixar arquivos silenciosamente com o curl ou o wget, use a opção “-silent” (para o curl) ou -quiet (para o wget). Lembre-se de que urls com “&” podem causar confusão; conforme seu shell (bash, csh, tcsh), será previso colocar aspas (simples ou duplas) em torno do url.

O anacron é o daemon que completa o cron para computadores que não estão ligados o tempo todo, realizando-as poucos minutos após a inicialização da máquina. É por isso que as tarefas no arquivo /etc/anacrontab são iniciadas com o comando nice, o qual reduz suas prioridades de execução, e assim, limita seus impactos no resto do sistema. Existe também o “at”, que executa um comando em um momento específico no futuro. Ele recebe o horário e data desejados como parâmetros de linha de comando e o comando a ser executado em sua saída padrão. Veja mais na documentação do Debian.

2 comments

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.