systemd timers (visão geral)
Esta aula apresenta uma visão geral dos timers do systemd, comparando-os com o cron, explicando as units básicas envolvidas, quando utilizá-los e fornecendo exemplos práticos de criação e gerenciamento de timers.
Os timers do systemd são uma alternativa moderna e poderosa ao cron para agendamento de tarefas no Linux. Eles fazem parte do sistema de inicialização systemd, presente na maioria das distribuições Linux atuais. Nesta aula, exploraremos os conceitos fundamentais dos timers, suas vantagens sobre o cron, como funcionam as units envolvidas e veremos exemplos práticos de criação e gerenciamento.
Diferentemente do cron, que é um daemon separado com sua própria sintaxe e configuração, os timers do systemd são integrados ao gerenciador de serviços. Isso significa que eles aproveitam recursos como dependências, paralelismo, logs estruturados e integração com o sistema de unidades. Além disso, os timers podem ser mais flexíveis, oferecendo opções como disparo em eventos, calendars expressivos e controle fino de ativação.
Timers vs cron
O cron é um agendador de tarefas clássico, presente no Unix desde os anos 70. Ele lê arquivos crontab e executa comandos em horários específicos, com granularidade de minuto. Apesar de simples e amplamente conhecido, o cron tem limitações: não integra bem com serviços do systemd, não oferece gerenciamento de dependências, e a execução de tarefas que precisam de um ambiente completo pode ser problemática.
Os timers do systemd, por outro lado, são units que ativam outras units (geralmente serviços) de acordo com um calendário ou eventos. Eles oferecem vantagens como:
- Integração com o systemd: podem ser iniciados no boot, ter dependências e ser gerenciados com systemctl.
- Logs e diagnóstico: a saída do serviço é capturada no journal, facilitando a depuração.
- Flexibilidade: suportam expressões de calendário complexas, como 'Mon..Fri 10:00' ou '*-*-* 00,12:00:00'.
- Eventos: podem ser acionados por eventos, como alterações em arquivos ou ativação de outros serviços.
- Persistência: podem ser configurados para executar tarefas que foram perdidas durante o desligamento (com Persistent=true).
No entanto, o cron ainda é útil para tarefas simples e em sistemas sem systemd. A escolha entre cron e timers depende do contexto: para sistemas modernos com systemd, os timers são preferíveis.
Units básicas
Os timers do systemd são definidos em units de tipo .timer. Cada timer possui uma unit de serviço (.service) associada, que é executada quando o timer dispara. A unit de serviço define o que fazer, e a unit de timer define quando fazer.
A unit de timer contém seções como [Unit] e [Timer]. A seção [Unit] descreve o timer e pode incluir dependências, como Wants ou Requires. A seção [Timer] especifica o agendamento, com diretivas como OnCalendar, OnBootSec, OnUnitActiveSec e Persistent.
A unit de serviço associada é uma unit normal, que pode ser do tipo oneshot (executa uma vez) ou simple. O nome da unit de serviço deve corresponder ao nome do timer, exceto pela extensão. Por exemplo, um timer chamado backup.timer espera um serviço chamado backup.service.
Exemplo de estrutura básica:
# /etc/systemd/system/meu-timer.timer
[Unit]
Description=Executa meu serviço periodicamente
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.targetE o serviço correspondente:
# /etc/systemd/system/meu-timer.service
[Unit]
Description=Meu serviço agendado
[Service]
Type=oneshot
ExecStart=/usr/local/bin/meu-script.shApós criar os arquivos, é necessário recarregar o systemd (systemctl daemon-reload) e habilitar e iniciar o timer (systemctl enable --now meu-timer.timer).
Quando usar
Os timers do systemd são recomendados em várias situações:
- Tarefas agendadas em sistemas que já usam systemd: é mais consistente gerenciar tudo com o mesmo conjunto de ferramentas.
- Tarefas que precisam de dependências: por exemplo, esperar que um serviço esteja ativo antes de executar.
- Tarefas que precisam de relatórios de execução: o journal do systemd captura a saída, facilitando auditoria.
- Tarefas que devem ser executadas mesmo se o sistema estiver desligado no horário agendado: com
Persistent=true, o timer executa a tarefa no próximo boot. - Tarefas que precisam de agendamentos complexos: como 'a cada 5 minutos durante horário comercial' ou 'no primeiro dia de cada mês, às 3h'.
Por outro lado, se você precisa de um agendamento muito simples e não quer lidar com a sintaxe de units, o cron pode ser mais direto. Além disso, em ambientes sem systemd (como containers minimalistas), o cron é a única opção.
Exemplos
Vamos criar um exemplo completo: um timer que executa um script de backup todas as noites às 2h30, com persistência para executar se o sistema estiver desligado.
Primeiro, o script de backup (em /usr/local/bin/backup.sh):
#!/bin/bash
tar -czf /backup/backup-$(date +%Y%m%d).tar.gz /dados
echo "Backup concluído em $(date)"Torne-o executável:
chmod +x /usr/local/bin/backup.shCrie o serviço /etc/systemd/system/backup.service:
[Unit]
Description=Backup diário
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.shCrie o timer /etc/systemd/system/backup.timer:
[Unit]
Description=Timer para backup diário
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
[Install]
WantedBy=timers.targetAgora, recarregue o systemd e ative o timer:
systemctl daemon-reload
systemctl enable --now backup.timerVerifique o status do timer:
systemctl status backup.timerPara listar todos os timers ativos:
systemctl list-timersOutro exemplo: um timer que executa um serviço a cada 5 minutos durante horário comercial (segunda a sexta, 9h às 18h). A expressão de calendário seria:
OnCalendar=Mon..Fri 09..18:00/5Isso significa de segunda a sexta, das 9h às 18h, a cada 5 minutos. É possível combinar várias diretivas OnCalendar em um timer, e o serviço será executado se qualquer uma delas corresponder.
Para testar um timer manualmente, use systemctl start backup.timer (inicia o timer, não o serviço) e systemctl start backup.service para executar o serviço diretamente.
Boas práticas
Ao usar timers do systemd, considere as seguintes práticas:
- Nomeie as units de forma consistente: o timer e o serviço devem ter o mesmo nome base.
- Use
Persistent=truepara tarefas que não podem ser perdidas, como backups. - Defina
RandomizedDelaySecpara evitar que muitos timers disparem ao mesmo tempo. - Monitore os timers com
systemctl list-timerse verifique logs comjournalctl -u backup.service. - Teste o serviço manualmente antes de agendar.
- Use
OnCalendarcom expressões claras; consulte a documentação para a sintaxe completa.
Exercícios
Crie um timer que execute um serviço chamado
limpeza.servicetoda segunda-feira às 6h da manhã. Escreva as units completas.✓ Resposta:# limpeza.timer [Unit] Description=Timer para limpeza semanal [Timer] OnCalendar=Mon *-*-* 06:00:00 [Install] WantedBy=timers.target# limpeza.service [Unit] Description=Serviço de limpeza [Service] Type=oneshot ExecStart=/usr/local/bin/limpeza.shQual é a diferença entre
OnBootSeceOnUnitActiveSec? Dê um exemplo de uso de cada um.✓ Resposta:OnBootSecdefine um tempo relativo ao boot do sistema, por exemploOnBootSec=10minexecuta 10 minutos após o boot.OnUnitActiveSecdefine um tempo relativo à última ativação do serviço associado, por exemploOnUnitActiveSec=1hexecuta 1 hora após a última execução do serviço. Exemplo: um timer que executa 5 minutos após o boot (OnBootSec=5min) e um timer que executa a cada 30 minutos após a última ativação (OnUnitActiveSec=30min).Como você verificaria se um timer está ativo e qual o próximo horário de execução?
✓ Resposta: Use o comandosystemctl list-timerspara ver todos os timers, incluindo a próxima execução. Para um timer específico, usesystemctl status nome.timer.Explique o que faz a diretiva
Persistent=trueem um timer.✓ Resposta:Persistent=truefaz com que, se o sistema estiver desligado no horário em que o timer deveria disparar, o serviço seja executado imediatamente após o próximo boot. Isso é útil para tarefas como backups que não podem ser perdidas.Crie um timer que execute um serviço
verificacao.servicea cada 15 minutos, mas somente de segunda a sexta, das 8h às 20h. Escreva a diretivaOnCalendarcorrespondente.✓ Resposta:OnCalendar=Mon..Fri 08..20:00/15ouOnCalendar=Mon..Fri 08:00..20:00/15. A sintaxe correta éMon..Fri 08..20:00/15, que significa de segunda a sexta, das 8h às 20h, a cada 15 minutos.