coldwa.st
All guidesProgrammingWebDataToolsDatabasesHaskellConceptsCabal & buildsToolchainCompilerPerformanceEditor & HLS

cron · agendamento · unix

O que é o cron, exatamente?

By ColdwastUpdated Aug 7, 20268 min read#cron#agendamento#unix
Um temporizador mecânico Kodak de câmara escura sobre uma superfície de madeira, com o mostrador graduado em minutos
Um temporizador mecânico. O cron é a mesma ideia com mais campos: você descreve quando, e outra coisa lembra-se de agir.

Uma entrada cron são cinco campos de tempo e um comando. Por ordem: minuto, hora, dia do mês, mês, dia da semana.

30 4 * * 1  /usr/local/bin/backup.sh

Lê-se: minuto 30, hora 4, qualquer dia do mês, qualquer mês, dia da semana 1. Quatro e meia da manhã, às segundas.

O vocabulário de um campo

Cada campo aceita mais do que um número solto. * significa todos os valores. 1-5 é um intervalo. 1,15 é uma lista. */15 é um passo: um valor em cada quinze, ou seja quatro vezes por hora no campo dos minutos.

Dois campos aceitam também nomes: os meses de JAN a DEC, os dias da semana de SUN a SAT. E o campo do dia da semana tem uma esquisitice conhecida: tanto 0 como 7 significam domingo na maioria das implementações.

O campo que é um OU

Eis a parte que surpreende, e merece uma segunda leitura.

O dia do mês e o dia da semana são duas formas diferentes de nomear o mesmo dia. Se preencher apenas um e deixar o outro em *, o cron comporta-se exatamente como espera. Se preencher ambos, o POSIX especifica que um dia que corresponda a qualquer um dos campos dispara a tarefa.

É um OU, não um E.

Grande plano de um calendário de parede impresso com os nomes dos dias da semana numa coluna à esquerda e os números dos dias do mês numa grelha, com os meses em várias línguas

Portanto 0 0 1 * 1 não significa «no primeiro do mês, se calhar numa segunda». Significa no primeiro de cada mês, e em todas as segundas - cerca de cinco vezes mais execuções do que o previsto.

O raciocínio por trás da escolha defende-se. Um E faria com que quase nenhuma combinação disparasse: «o 31 quando calha numa sexta» acontece uma ou duas vezes por ano. O OU permite que uma só linha exprima «mensal e semanal» sem uma segunda entrada. Mas é o contrário do que a sintaxe sugere, e é aí que as tarefas agendadas correm em silêncio nos dias errados.

Os atalhos, e porque não são portáveis

Muitas implementações aceitam @daily, @hourly, @weekly, @monthly e @reboot. São cómodos e não fazem parte do POSIX: vêm do Vixie cron e dos seus descendentes.

Numa máquina que controla, tanto faz. Em algo que tem de correr em qualquer lado - uma imagem de contentor, um script que distribui - os cinco campos explícitos são a opção segura. O @reboot em particular não tem equivalente algum na norma, e o seu comportamento depende inteiramente da implementação.

O que o cron não faz

Não recupera o perdido. Se a máquina estava desligada às 4:30, a tarefa das 4:30 não correu e não será relançada. O cron dispara por correspondência de relógio, não mantém uma fila de trabalho falhado.

Não lhe dá o seu ambiente de sessão. Uma tarefa cron corre com um PATH mínimo e sem nada do seu perfil de shell. O «funciona no meu terminal mas não no cron» mais comum é um comando encontrado por um PATH que o cron não tem. Use caminhos absolutos.

Não evita a sobreposição. Se uma tarefa agendada a cada cinco minutos demora seis, fica com duas cópias a correr. O cron arrancará a seguinte na mesma; o ficheiro de bloqueio é consigo, não com ele.

Não lhe diz que falhou. A saída vai por correio se o correio estiver configurado, e para lado nenhum se não estiver. Redirecione para um ficheiro de registo e veja-o, ou saberá pela cópia de segurança que falta.

Leia a expressão antes de confiar nela

Como o OU é invisível na sintaxe, uma expressão de aspeto correto pode estar errada de uma forma que só se manifesta semanas depois. Descodificá-la campo a campo antes de implantar custa segundos: é para isso que serve o descodificador de expressões cron deste site.

Um calendário com os nomes dos dias ao lado e os números na grelha. O cron tem um campo para cada um, e quando preenche ambos corresponde a um OU a outro, não aos dois juntos.