Como funciona o Marcelo de hora em hora na prática
A ideia central do Marcelo de hora em hora é automatizar a execução recorrente de um script ou tarefa com intervalo fixo de sessenta minutos. Parece simples, mas a implementação real costuma cobrar seu preço em variáveis que ninguém menciona nos tutoriais introdutórios. Vou explicar o que realmente acontece quando você coloca isso no ar, com base no que eu vi funcionar e no que quebrou meu deploy diversas vezes. O mecanismo básico envolve três peças: o cron jobs do sistema operacional (Linux ou macOS), o interpretador do script (Python, Bash, PHP) e um loop de controle interno que verifica se a execução anterior foi concluída antes de disparar a próxima. Sem esse loop, você acaba com execuções sobrepostas que geram conflito de recursos, especialmente se a tarefa principal leva mais de cinquenta minutos para rodar.
Instalação do marcelo de hora em hora no servidor
Comece pelo básico. Você precisa de acesso SSH ao seu servidor ou VPS, preferably rodando Ubuntu ou Debian. Instale as dependências antes de mexer em qualquer configuração: sudo apt update && sudo apt install -y cron python3 python3-pip git -y
Clone o repositório ou baixe o arquivo do Marcelo de hora em hora diretamente do link fornecido pelo autor. A maioria dos scripts modernos vai para /opt ou /home/seu_usuario/scripts/. Eu sempre recomendo o /opt por razões de permissão, mas se seu usuário não tiver acesso sudo contínuo, use o diretório home mesmo. Após baixar, dê permissão de execução:
chmod +x marcelo_hora_em_hora.sh O problema que eu encontrei na terceira vez que fiz essa instalação foi que o script pedia dependências Python que não estavam no PATH padrão do cron. O cron usa um PATH minimalista, diferente do seu shell interativo. A solução foi adicionar esta linha no topo do arquivo .sh ou configurar o PATH explicitamente no crontab:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin Isso resolveu o erro de comando não encontrado que aparecia todas as vezes. Sem essa variável, o cron não achava nem mesmo o python3, mesmo que funcionasse perfeitamente quando você rodava manualmente no terminal.
Configurando o agendamento para execução a cada hora
A parte mais crítica é o crontab. Abra o editor com crontab -e e adicione a seguinte linha: 0 * * * * /caminho/para/marcelo_hora_em_hora.sh >> /var/log/marcelo_hora.log 2>&1
O parâmetro 0 * * * * significa: no minuto 0 de cada hora, execute. Se você precisar de intervalos diferentes, como a cada trinta minutos, use */30 no campo dos minutos. Mas para o padrão de hora em hora, essa configuração é suficiente. Uma observação importante: o log redirecionado para /var/log/marcelo_hora.log é essencial. Sem ele, você vai descobrir problemas apenas quando algo der errado sem nenhum registro visível. Eu perdi duas noites tentando debugar um script porque o log estava sendo descartado pelo redirecionamento padrão do cron.
Variáveis de ambiente que costumam quebrar
Além do PATH, há outras variáveis que o cron não herda. A HOME, por exemplo. Se seu script precisa acessar arquivos no diretório pessoal do usuário (config.json, chaves SSH, certificados), o cron pode não conseguir encontrar esses arquivos porque a HOME padrão dele é / ou /root, dependendo da distribuição. A solução mais robusta é exportar todas as variáveis necessárias dentro do próprio script antes de executá-lo, ou criar um arquivo .env e carregar ele no início da execução. No caso do Marcelo de hora em hora, especialmente se ele faz requisições HTTP ou acessa APIs, as variáveis de API_KEY e BASE_URL precisam estar definidas antes do início do loop.
Eu testei usar dotenv no Python com a biblioteca python-dotenv, e funcionou perfeitamente. Basta criar um arquivo .env na mesma pasta do script com suas credenciais e adicionar import os + dotenv.load_dotenv() no início do código. Isso evita que você precise manipular variáveis de ambiente diretamente no crontab, que é muito mais propenso a erros de digitação.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Edge case: quando a execução ultrapassa a janela horária
Aqui está o problema que a maioria dos tutoriais ignora. Se o Marcelo de hora em hora levar mais de sessenta minutos para completar uma execução, a próxima instância será disparada pelo cron enquanto a anterior ainda está rodando. Dependendo do que o script faz, isso pode corromper dados, duplicar registros ou causar falhas silenciosas que só aparecem dias depois. O workaround que eu desenvolvi foi adicionar um arquivo de trava (lock file) no início da execução. O script cria um arquivo .lock na mesma pasta e o remove ao final. No início de cada execução, ele verifica se o arquivo de trava existe. Se existir, o script sai imediatamente sem fazer nada.
No Bash, isso fica assim: if [ -f "/caminho/para/script.lock" ]; then exit 0; fi touch /caminho/para/script.lock execução principal rm -f /caminho/para/script.lock
No Python, o recomendado é usar a biblioteca locking padrão ou até mesmo o módulo tempfile, que é mais limpo. A diferença é que o lock file em Bash é trivial de implementar, mas exige cuidado com a remoção. Se o script abortar violentamente (SIGKILL, crash), o arquivo de trava permanece e bloqueia todas as execuções seguintes até você removê-lo manualmente. Uma alternativa mais segura é usar o flock, que é uma ferramenta de bloqueio de arquivos nativa do Linux. Em vez de criar e deletar arquivos manualmente, você envolve a execução do script com flock:
flock -n /tmp/marcelo.lock /caminho/para/marcelo_hora_em_hora.sh O flock com a flag -n tenta adquirir o lock de forma não bloqueante. Se não conseguir, sai com código 1 sem executar. Isso elimina completamente o risco de lockfile órfão porque o kernel libera o lock automaticamente quando o processo morre.
Monitoramento e alertas
Ter o script rodando todo hora não adianta se você não souber quando ele para de funcionar. Eu configurei um wrapper simples que envia um alerta via webhook para o Telegram sempre que o script falha ou demora mais de noventa minutos para executar. O wrapper basicamente cronometra o tempo de execução com o comando time e verifica o código de saída. Se o código for diferente de zero, dispara o alerta. Em produção, usei um script Python que monitora o PID do processo e verifica se ele ainda está ativo na janela esperada. Isso evita o cenário clássico de "o cron está rodando mas o processo morreu e ninguém percebeu".
Também é útil verificar periodicamente o tamanho do arquivo de log. Se o log parar de crescer por mais de duas horas consecutivas, alguma coisa está errada. Um comando simples como tail -f /var/log/marcelo_hora.log durante trinta segundos já revela se há atividade.
Limitações reais do método
O Marcelo de hora em hora funciona bem para tarefas de baixa complexidade e com tempo de execução previsível. Se sua tarefa envolve processamento pesado, chamadas externas com latência variável ou manipulação de arquivos grandes, o modelo de cron simples não é adequado. Nesse caso, considere usar ferramentas como Celery com Redis, ou até mesmo Apache Airflow para orquestração mais sofisticada. O cron também não oferece retry automático. Se uma execução falhar, ela simplesmente não será repetida até a próxima hora. Para tarefas críticas, isso é um risco real. Nesse cenário, o ideal é implementar um sistema de retry com backoff exponencial dentro do próprio script, ou usar um gerenciador de tarefas como o GNU parallel.
Outra limitação importante: se o servidor desligar ou reiniciar, o cron volta automaticamente em instalações modernas com systemd, mas se houver qualquer problema na inicialização do serviço cron, o agendamento pode não retomar. Sempre verifique se o serviço está ativo com systemctl status cron após qualquer manutenção no servidor.
Checklist rápido antes de colocar em produção
Antes de deixar o Marcelo de hora em hora rodando sozinho, confirme os seguintes pontos: O script roda sem erros quando executado manualmente sob o mesmo usuário do cron. As variáveis de ambiente estão todas definidas e acessíveis. O lock mechanism está implementado para evitar execuções sobrepostas. O log está sendo escrito em um caminho com permissão de escrita. Um teste de falha simulada foi realizado para verificar o comportamento do sistema de alertas. O tempo médio de execução é inferior a quarenta e cinco minutos para deixar margem de segurança.
Se algum desses pontos estiver em aberto, não suba para produção. Eu já vi deploy quebrado por causa do item dois em servidores que pareciam idênticos aos de desenvolvimento, só que com configurações de variáveis de ambiente ligeiramente diferentes. A diferença entre um ambiente de teste limpo e um servidor de produção sujo é onde a maior parte dos problemas aparece.