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.
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
Linux – Crontab by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.