Agendamento de tarefas com at, cron e timers do systemd

LinuxBeginner
Pratique Agora

Introdução

Administradores Linux agendam tarefas de várias maneiras. O comando at agenda tarefas únicas, o cron agenda tarefas recorrentes a partir de campos de tempo simples, e os timers do systemd agendam serviços do systemd utilizando o modelo de dependência e registro (logging) do próprio systemd.

Neste laboratório, você criará um script de comando e o agendará de três formas diferentes. Você inspecionará os serviços de agendamento, colocará uma tarefa única na fila do at, configurará um arquivo de configuração do cron, criará um par de serviço e timer do systemd e testará manualmente o serviço por trás do timer.

Inspecionar agendadores e criar um script de tarefa

Nesta etapa, você confirmará se os serviços de agendamento estão em execução e criará um pequeno script que será chamado por todas as tarefas agendadas.

Entre no diretório do projeto.

cd /home/labex/project

Verifique o daemon de tarefas únicas e o daemon do cron. O comando systemctl is-active imprime active quando um serviço está em execução.

systemctl is-active atd crond

Liste os timers do systemd existentes. A saída mostra o próximo horário de execução, a unidade de timer e a unidade de serviço que ela ativa.

systemctl list-timers --all --no-pager | sed -n '1,10p'

Crie um script que anexa uma linha com carimbo de data/hora a um arquivo de log. O primeiro argumento, $1, torna-se o rótulo que identifica qual agendador executou o script.

cat > /home/labex/project/scheduled-note.sh <<'EOF'
#!/bin/bash
echo "$(date '+%F %T') $1" >> /home/labex/project/schedule-events.log
EOF

Torne o script executável.

chmod 755 /home/labex/project/scheduled-note.sh

Execute o script manualmente uma vez.

/home/labex/project/scheduled-note.sh manual-run
tail -n 1 /home/labex/project/schedule-events.log

A linha do log deve terminar com manual-run.

Colocar uma tarefa única na fila do at

Nesta etapa, você agendará uma tarefa única com o at. Isso é útil para trabalhos que devem ocorrer apenas uma vez no futuro, como uma tarefa de manutenção temporária.

Coloque o script na fila para ser executado daqui a duas horas. O comando a ser executado é enviado via pipe para o at.

echo "/home/labex/project/scheduled-note.sh at-job" | at now + 2 hours

Liste as tarefas na fila.

atq

Salve o ID da tarefa da primeira linha do atq. O ID da tarefa é o primeiro campo na saída.

job_id="$(atq | awk 'NR==1 {print $1}')"
echo "$job_id" > /home/labex/project/at-job.id
cat /home/labex/project/at-job.id

Inspecione o conteúdo da tarefa na fila. O comando at -c imprime o script da tarefa gerado; as linhas finais devem incluir o comando que você agendou.

at -c "$job_id" | tail -n 12

Configurar um arquivo de drop-in do cron

Nesta etapa, você configurará uma tarefa recorrente do cron com um arquivo em /etc/cron.d. Os arquivos neste diretório incluem um campo de usuário, para que o sistema saiba qual conta deve executar o comando.

Crie um arquivo cron que execute o script a cada minuto como o usuário labex. A linha PATH fornece ao cron um caminho de busca de comandos previsível.

sudo tee /etc/cron.d/rhcsa-schedule-demo >/dev/null <<'EOF'
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * labex /home/labex/project/scheduled-note.sh cron-job
EOF

Defina o modo do arquivo como 644. Os arquivos do cron devem ser legíveis e não devem ser graváveis por usuários comuns.

sudo chmod 644 /etc/cron.d/rhcsa-schedule-demo

Recarregue o crond para que ele reconheça o arquivo imediatamente.

sudo systemctl reload crond

Inspecione o arquivo que você criou.

sudo cat /etc/cron.d/rhcsa-schedule-demo

Os campos de agendamento * * * * * significam a cada minuto.

Criar um serviço e um timer do systemd

Nesta etapa, você criará um serviço do systemd e um timer que o ativa. Um timer não executa um comando diretamente; ele inicia uma unidade de serviço.

Serviços do sistema devem executar comandos a partir de caminhos executáveis do sistema, não do diretório de trabalho de um usuário. Instale uma cópia do seu script em /usr/local/bin.

sudo install -m 755 /home/labex/project/scheduled-note.sh /usr/local/bin/rhcsa-scheduled-note
sudo restorecon /usr/local/bin/rhcsa-scheduled-note 2>/dev/null || true
ls -l /usr/local/bin/rhcsa-scheduled-note

Crie a unidade de serviço. Type=oneshot é apropriado para um comando que é executado e finaliza.

sudo tee /etc/systemd/system/rhcsa-schedule-demo.service >/dev/null <<'EOF'
[Unit]
Description=Write RHCSA schedule demo entry

[Service]
Type=oneshot
User=labex
ExecStart=/usr/local/bin/rhcsa-scheduled-note timer-job
EOF

Crie a unidade de timer. OnBootSec=2min agenda uma primeira execução após a inicialização, e OnUnitActiveSec=5min agenda execuções posteriores em relação à ativação anterior.

sudo tee /etc/systemd/system/rhcsa-schedule-demo.timer >/dev/null <<'EOF'
[Unit]
Description=Run RHCSA schedule demo periodically

[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
Unit=rhcsa-schedule-demo.service

[Install]
WantedBy=timers.target
EOF

Recarregue o systemd, habilite o timer para a inicialização e inicie-o agora. Separar enable e start deixa claro qual comando torna o timer persistente e qual comando o ativa imediatamente.

sudo systemctl daemon-reload
sudo systemctl enable rhcsa-schedule-demo.timer
sudo systemctl start rhcsa-schedule-demo.timer

Inspecione o timer.

systemctl list-timers rhcsa-schedule-demo.timer --all --no-pager

O timer deve aparecer na lista e deve ativar o rhcsa-schedule-demo.service.

Testar o serviço do timer e remover a tarefa do at

Nesta etapa, você iniciará manualmente o serviço usado pelo timer. Isso verifica o comando imediatamente sem esperar pela próxima ativação agendada do timer. Você também removerá a tarefa do at que estava na fila, pois ela era apenas para prática.

Inicie o serviço manualmente.

sudo systemctl start rhcsa-schedule-demo.service

Inspecione o log.

tail -n 5 /home/labex/project/schedule-events.log

Uma linha deve terminar com timer-job.

Remova a tarefa do at que estava na fila usando o ID da tarefa salvo anteriormente.

job_id="$(cat /home/labex/project/at-job.id)"
atrm "$job_id"

Confirme que a tarefa não está mais na fila.

atq

Resumo

Você praticou três métodos de agendamento. Você inspecionou o atd, crond e os timers do systemd, criou um script de comando agendado reutilizável, colocou na fila e inspecionou uma tarefa única do at, configurou um arquivo de drop-in do cron, instalou um comando seguro para serviços em /usr/local/bin, criou um par de serviço e timer do systemd, testou manualmente o serviço do timer e removeu a tarefa temporária do at.