Linux – Crontab

O utilitário Cron é um agendador de tarefas em Unix-like para executar tarefas repetidas vezes, baseado em (minutos, horas, dias, semanas, meses ou ano), então é com ele que você pode configurar um script para por exemplo todos os dias a meia-noite realizar backup do banco de dados, para tarefas mais simples ou que será executada uma unica vez é interessante usar o comando at.

Um outro comando que se vê no Linux é o anacron, alinhado ao cron mas que difere onde consegue executar tarefas atrasadas, caso o servidor/desktop esteja desligado, ao ligar consegue executar tarefas que não foram neste período, mas não será abordado neste post.

O nome Cron não tem sua definição de nome muito clara, em alguns sites você encontra a referencia da palavra grega chronos(tempo) em outros “Command Run On Notice” ou mesmo “Commands Run Over Night”.

Vamos então conhecer a sua estrutura, seus diretórios e como se criar rotinas agendadas para executar as tais tarefas, além de poder bloquear e liberar usuários e algumas expressões especiais para usar em rotinas.

Primeiro de tudo você deve saber que o “cron” conta com duas ferramentas:

cron Daemon que iniciado automaticamente no boot para então executar as tarefas agendadas
crontab Ferramenta para Listar, instalar e deletas as rotinas de agendamento, podendo ser administradas por usuários separadamente

 

Comando crontab

O crontab é o único comando que utilizaremos neste post, para vários funções, vamos ver as opções disponíveis:

-l Lista os comandos/regras adicionado no crontab do usuário corrente
-e Abre o editor (Nano, Vi ou Vim) para editar as rotinas configuradas para você alterar
-r Remove o crontab do usuario corrente
-u Possuindo acesso root, especificando -u você pode listar, editar ou remover qualquer crontab de qualquer usuário

Vamos a um exemplo pratico com meu usuário:

$ crontab -l
no crontab for cleiton

No caso não tenho o crontab configurado para este usuário, irei criar/editar um e vamos ver o que acontece:

$ crontab -e
no crontab for cleiton - using an empty one

# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command


# Criando minha primeira tarefa/rotina agendada
:wq
crontab: installing new crontab

No caso acima abriu uma estrutura padrão, eu apenas adicione “Criando minha primeira tarefa/rotina agendada” como um comentário usando # e salvei e sai usando :wq (uso o vim para editor padrão ;) )

Agora se eu listar as regras novamente:

$ crontab -l
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command


# Criando minha primeira tarefa/rotina agendada

É importante saber que o crontab baseia-se nos usuários em /etc/passwd, outro detalhe é onde ficam estes arquivos dos usuários que podemos listar e editar, no caso ele fica em /var/spool/cron/crontabs/ dentre deste diretório haverá um arquivo com o nome de cada usuário que sera o crontab respectivo.

Listando o conteúdo do meu notebook, temos:

$ sudo ls /var/spool/cron/crontabs/
cleiton  root

 

 

Criando tarefas/rotinas agendadas

Como já ouvimos dizer que uma imagem vale mais que mil palavras, segue uma imagem da estrutura para criar o agendamento de uma tarefa, chamando aqui tarefa qualquer script, aplicação ou rotina direta no crontab.

Imagem obtida do site http://www.linuxconfig.org.

cron

Um exemplo de agendamento de um script baseado na informação da imagem acima seria.

36 2 * * 7 root /usr/local/sbin/backup.sh

Uma tarefa no crontab o correto é ler da esquerda para a direita sendo a primeira opção o minuto(0-59) e ae vai a sequencia hora(0-23), dia(1-31), mês(1-12), dia da semana(0-7), usuário e por ultimo o comando ou script a ser executado.

Quando se usa o “*” é mesma coisa que dizer qualquer dia e qualquer mês ou mesmo parâmetros em branco, então para executar o script backup.sh podemos dizer que será executado todos os domingos as 2:36 da manhã, correto? Sim!

E se eu quiser executar o backup do banco de dados todos os dias a meia-noite?

00 00 * * * root /usr/local/sbin/backup.sh

Executando a cada hora todos os dias:

00 * * * * root /usr/local/sbin/backup.sh

Executar um script no dia 05 e no dia 20 as 08:15 da manhã:

15 8 05 * * root /usr/local/bin/enviar_email_pagamento.sh
15 8 20 * * root /usr/local/bin/enviar_email_adiantamento.sh

Executar um script de 5 em 5 minutos de segunda a sexta-feira para checar a rede:

*/5 * * * 1-5 /root/scripts/check-network.sh

Executar um script ao meio-dia e a meia-noite na seguna-feira e na sexta-feira:

00 00,12 * * 1,5 /usr/local/bin/optimize_database.sh

Agora um script para ser executado todos os dias as 06:01, 12:01 e 18:01 mas ignorando a saída e qualquer erro:

01 06,12,18 * * * /usr/local/bin/bandwidth_network.sh >/dev/null 2>&1

Um script útil que uso é eliminar arquivos “temporários”, segue um exemplo que uso em alguns servidores:

# Verifica aos domingos e removendo arquivos no /tmp com mais de 30 dias sem acesso/alteração
30 23 * * 0 find /tmp/ -atime +30 -delete

# Verifica diariamente e remove arquivos maiores de 100M com mais de 60 dias sem acesso/alteração
23 0 * * * find /var/samba/trash/ -type f -size +50m  -atime +60 -delete

Acho que deu para ter uma base geral de como criar vários tipos de agendamentos e misturando vários casos, e dessa maneira você pode alimentar o arquivo do seu usuário com varias regras de agendamento.

 

Avançando no crontab

No /etc temos um arquivo chamado crontab, vamos ver o conteúdo dele:

$ cat /etc/crontab 
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

O curioso deste arquivo são as linhas 12 a 15, onde cada linha um possui um regra para agendamento, a regra de horário pode diferenciar dependendo da sua distribuição Linux, vamos ver estes diretórios:

$ tree /etc/cron.*
/etc/cron.d
├── anacron
└── sysstat
/etc/cron.daily
├── 0anacron
├── apt
├── aptitude
├── bsdmainutils
├── dpkg
├── google-chrome -> /opt/google/chrome/cron/google-chrome
├── libvirt-bin
├── lighttpd
├── logrotate
├── man-db
├── mlocate
├── passwd
├── samba
└── sysstat
/etc/cron.hourly
/etc/cron.monthly
└── 0anacron
/etc/cron.weekly
├── 0anacron
├── apt-xapian-index
└── man-db

Então temos a seguinte estrutura e baseado na regra de cron o seguinte uso:

/etc/cron.daily Todos os dias as 6:25
/etc/cron.hourly A cada hora e 17 minutos
/etc/cron.monthly Todo primeiro dia do mês as 6:52
/etc/cron.weekly  Todo domingo as 6:47

Dessa maneira, os scripts que tiverem em cada um destes diretórios, será executado a cada hora, dia, semana ou mês, quem faz esta tarefa de acesso e execução é o run-parts, neste diretório os arquivos são scripts e aplicações em si e não regra do crontab.

Um outro diretório do cron é o /etc/cron.d, neste diretório encontram-se vários arquivos contendo regras de agendamento e caminho de scripts/aplicações/comandos a serem executados, a vantagem de criar um arquivo neste diretório com regra para agendamento é de centralização.

Caso tenha uma aplicação e precisa agendar uma tal rotina, é uma boa pratica criar um arquivo no /etc/cron.d com o nome da sua aplicação, e é desta maneira que muitos pacotes e aplicativos fazem, ou utilizar o /etc/cron.daily, /etc/cron.hourly e os demais.

 

Expressões especiais

Para facilitar algumas rotinas, existem alguns comandos especiais para adicionar nos agendamentos, vamos ver a tabela abaixo:

@reboot Executa ao iniciar
@yearly Executa uma vez ao ano, “0 0 1 1 *”
@annually Igual ao @yearly
@monthly Executa uma vez ao mês, “0 0 1 * *”
@weekly Executa uma vez na semana, “0 0 * * 0”
@daily Executa uma vez ao dia, “0 0 * * *”
@midnight Igual ao @daily
@hourly Executa a cada hora, “0 * * * *”

Uso com frequência o @reboot, para executar um script/comando ao iniciar, um exemplo de uso:

# Altera valor peso swap para 25
@reboot echo 25 > /proc/sys/vm/swappiness

 

Bloqueando usuários

Um recurso interessante e que deveria ser empregado em alguns casos como em servidores onde possui vários usuários seria bloquear o uso do crontab por usuário, para isso existem dois arquivos para realizar este controle.

/etc/cron.allow Usuarios liberados para criar agendamento
/etc/cron.deny Usuarios bloqueados para criar agendamento

O nome de usuário que adicionar em /etc/cron.deny o usuário não poderá criar um arquivo de agendamento de tarefas, vamos verificar:

# echo "cleiton" > /etc/cron.deny
# exit
$ crontab -e
You (cleiton) are not allowed to use this program (crontab)
See crontab(1) for more information
$ cat /etc/cron.{deny,allow}
cleiton

Mas é importante saber que /etc/cron.allow precede sobre /etc/cron.deny então um usuário em ambos o mesmo passara a ter acesso ao crontab, verificando:

# echo "cleiton" > /etc/cron.allow 
# exit
$ cat /etc/cron.{deny,allow}
cleiton
cleiton
$ crontab -e
crontab: installing new crontab

Uma pratica bacana seria adicionar todos usuários comuns do /etc/passwd no /etc/cron.deny e só adicionar no /etc/cron.allow os que deseja liberar acesso. Você pode criar uma rotina no cron para diariamente fazer isso, caso seja um servidor que sempre recebe novos usuários como de repositórios e arquivos por exemplo.

Dica

Você pode usar vários editor do Linux para manipular os arquivos do cron, mas se por exemplo ao executar crontab -e abrir o editor nano e você deseja usar o vim, pode fazer o seguinte procedimento.

$ export EDITOR=vim

Agora executando crontab -e novamente, ele irá abrir com o vim ;)

Finalizamos o artigo sobre crontab, onde abordamos por completo toda sua estrutura, recursos, configuração e com vários exemplos, agora você tem tudo do que precisa para criar seus scripts e rotinas.

Espero que tenham gostado, até a próxima!

 

Referências

http://linux.die.net/man/5/crontab

http://linux.die.net/man/1/crontab

Share Button

CC BY-NC-SA 4.0 Linux – Crontab by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.