8 pontos por GN⁺ 2026-06-02 | 2 comentários | Compartilhar no WhatsApp
  • Timers do systemd são um substituto prático para o cron, executando unidades como .service de acordo com uma agenda e oferecendo gerenciamento mais claro de histórico, saída e ambiente
  • O cron tradicional tem fraquezas como $PATH ambíguo, stdout/stderr que se perdem facilmente, histórico de execução difícil de rastrear e uma sintaxe de agendamento difícil de ler
  • Timers conectam um .timer e um .service com o mesmo stem e expressam execuções baseadas em horário ou evento com OnCalendar, OnBootSec e OnUnitActiveSec
  • Com systemd-analyze calendar e systemctl list-timers, dá para verificar expressões de tempo e o próximo horário de execução, e WakeSystem= pode acordar a máquina para executar mesmo em estado de suspensão
  • RandomizedOffsetSec e FixedRandomDelay= reduzem picos de execuções simultâneas, e Persistent= compensa execuções perdidas enquanto a máquina estava inativa logo após ela voltar a ficar online

Por que usar timers do systemd como substituto do cron

  • cron job é um termo amplamente usado para se referir ao elemento básico da computação que executa tarefas conforme uma agenda, como “execute isto todos os dias” ou “execute aquilo todo mês”, mesmo quando não se trata literalmente do daemon cron
  • Um timer do systemd é uma unidade do systemd que executa outra unidade, normalmente um .service, de acordo com uma agenda específica, e pode servir como substituto funcional do daemon cron tradicional
  • O cron tradicional tem algumas limitações práticas
    • Por causa de configurações ambíguas de $PATH, é difícil prever o resultado da execução de scripts
    • Saídas em stdout e stderr muitas vezes vão para um buraco negro ou são enviadas para o sistema de e-mail do host
    • É difícil rastrear e consultar o histórico de execução
    • Sintaxes de agendamento como 01,31 04,05 1-15 1,6 * não são fáceis de ler nem intuitivas para humanos
  • Timers do systemd reduzem esses problemas e ainda oferecem configurações de calendário parecidas com expressões no estilo cron

Estrutura básica: serviço e timer

  • Um timer do systemd precisa de algo para executar, e uma unidade .service pode ser vista, em termos lógicos, como um script
  • Por exemplo, se você colocar a seguinte unidade em /etc/systemd/system/roulette.service, instalará um serviço que desliga o computador com probabilidade de 1 em 10
[Unit]
Description=1 in 10 chance to break your chains

[Service]
ExecStart=/usr/bin/env bash -c '[[ $(($RANDOM % 10)) == 0 ]] && systemctl poweroff || echo LIVE ANOTHER DAY'
  • ExecCondition= é uma forma mais integrada de expressar execução condicional com opções do serviço systemd, deixando mais claro no nível da unidade a pergunta “deve continuar executando?”
[Unit]
Description=1 in 10 chance to break your chains

[Service]
ExecCondition=/run/current-system/sw/bin/bash -c '[[ $(($RANDOM % 10)) == 0 ]]'
ExecStart=/run/current-system/sw/bin/systemctl poweroff
  • Se a condição não for satisfeita, o journal registra uma mensagem mais clara
May 05 11:05:32 diesel systemd[3117]: Condition check resulted in 1 in 10 chance to break your chains being skipped.
  • Em geral, aproveitar as opções fornecidas pelo systemd oferece uma experiência melhor do que fazer tudo via script manualmente
    • OnFailure= pode ser usado para reagir a falhas no script de serviço
    • Restart= pode ser usado para tentar recuperar falhas transitórias

Conectando e executando a unidade timer

  • Se você criar /etc/systemd/system/roulette.timer com o mesmo stem do arquivo, poderá conectar o timer a roulette.service
[Unit]
Description=impending destruction

[Timer]
OnCalendar=10:00

[Install]
WantedBy=timers.target
  • Por padrão, a configuração Unit= do timer escolhe a unidade de serviço com o mesmo stem e o sufixo .service
    • Neste exemplo, roulette.service é escolhida
    • Se quiser executar uma unidade de serviço com outro nome, você pode alterar Unit=
  • O alvo de ExecStart= não é executado como comando de shell por padrão
    • Alvos com caminho absoluto devem ser tratados como scripts ou como interpretadores que esperam um script em forma de string como argumento
    • ExecStart=/usr/bin/echo Hello | /usr/bin/awk não funciona nesse contexto, porque o pipe não tem significado aqui
  • Argumentos de ExecStart= não herdam variáveis de ambiente além de alguns padrões do gerenciador do sistema
    • O $PATH padrão é quase vazio
    • Executar /usr/bin/env funciona como uma proteção simples para disponibilizar itens como systemctl
    • Se você tivesse usado apenas ExecStart=/usr/bin/bash, entradas padrão seriam adicionadas ao $PATH, mas usar env é uma camada extra de segurança
  • É possível executar o serviço diretamente, sem timer
systemctl start roulette
  • Um serviço sem seção [Install] não pode ser enabled, e nessa estrutura o timer é a forma padrão de executar o serviço de maneira consistente
  • O systemctl funciona por padrão sobre roulette.service mesmo sem o sufixo explícito
  • Aplicar systemctl start a uma unidade .timer coloca o timer em funcionamento, mas não executa imediatamente o serviço definido em Unit=
systemctl start roulette.timer
  • status mostra quando o timer será executado na próxima vez
systemctl status roulette.timer
Trigger: Sat 2026-04-18 10:00:00 MDT; 35min left
  • O fluxo mais simples é criar o serviço que será executado, colocar um timer com agenda no mesmo local e iniciar o timer, não o alvo
  • Se a seção [Install] da unidade timer tiver WantedBy=, o timer também pode subir no boot
systemctl enable roulette.timer

Representação do tempo: eventos de calendário e durações

  • Em timers, a forma de expressar a agenda é importante, e é preciso distinguir entre intervalos recorrentes de tempo e eventos de calendário ou timestamps
  • A página de manual systemd.time(7) tem exemplos suficientes e vale como a primeira referência ao escrever timers
  • systemd-analyze pode validar e explicar expressões de tempo
systemd-analyze calendar '*-*-* *:*:*'
Normalized form: *-*-* *:*:*
    Next elapse: Sat 2026-04-18 16:44:26 MDT
       (in UTC): Sat 2026-04-18 22:44:26 UTC
       From now: 431ms left
  • Timers do systemd podem definir não só horários recorrentes baseados no relógio de parede, mas também durações recorrentes baseadas em algum evento anterior, algo que o cron tradicional não faz
  • A forma completa de daily significa executar todos os anos, todos os meses, todos os dias às 00:00:00
*-*-* 00:00:00
│ │ │ │  │  ╰── at second 00
│ │ │ │  ╰───── at minute 00
│ │ │ ╰──────── at hour 00
│ │ ╰────────── every day
│ ╰──────────── every month
╰────────────── every year
  • Você pode usar abreviações como daily, a forma completa e outros valores suportados por systemd.time(7), e validar suas suposições com systemd-analyze

Quando execuções baseadas em eventos fazem mais sentido

  • Em trabalhos reais, muitas vezes faz mais sentido dizer “execute depois de outro evento” do que “execute todo dia no mesmo horário”
  • Num trabalho de limpar diretórios temporários, se a expressão do cron tiver passado logo após o boot, pode quase não haver nada para limpar em /tmp
  • Expressar isso como “execute uma hora depois que o computador iniciar e depois execute a cada hora” combina melhor com o comportamento real do serviço e a lógica do agendamento
[Timer]
OnBootSec=1h
OnUnitActiveSec=1h
  • OnBootSec=1h significa executar uma vez uma hora após a máquina iniciar
  • OnUnitActiveSec=1h significa executar novamente uma hora após Unit= ter sido executada, fazendo com que o timer repita continuamente de forma implícita
  • Esse tipo de expressão periódica por duração costuma se encaixar melhor em casos de “execute de vez em quando” do que expressões como “execute nesse minuto de cada hora”
  • No exemplo de um bot do Slack que faz polling da API do Advent of Code, a expressão */15 do cron respeita a política de “a cada 15 minutos” da API, mas se todos fizerem polling do mesmo jeito, o tráfego pode se concentrar
  • Se você iniciar o timer depois de alterar o código e fizer com que ele execute a cada 15 minutos passados desde então, pode obter o comportamento necessário e ainda reduzir a chance do problema de thundering herd

Visualizando o estado dos timers de uma vez

  • systemctl list-timers é um comando de alto nível que resume a situação dos timers em uma máquina
systemctl list-timers
NEXT                                 LEFT LAST                                  PASSED UNIT                         ACTIVATES
Mon 2026-04-20 15:15:00 MDT      1min 40s Mon 2026-04-20 15:00:05 MDT        13min ago zfs-snapshot-frequent.timer  zfs-snapshot-frequent.service
Mon 2026-04-20 15:32:16 MDT         18min Mon 2026-04-20 14:22:15 MDT        51min ago fwupd-refresh.timer          fwupd-refresh.service
Mon 2026-04-20 16:00:00 MDT         46min Mon 2026-04-20 15:00:05 MDT        13min ago logrotate.timer              logrotate.service
Mon 2026-04-20 16:00:00 MDT         46min Mon 2026-04-20 15:00:05 MDT        13min ago zfs-snapshot-hourly.timer    zfs-snapshot-hourly.service
Tue 2026-04-21 00:00:00 MDT            8h Mon 2026-04-20 09:43:22 MDT     5h 29min ago zfs-snapshot-daily.timer     zfs-snapshot-daily.service
Tue 2026-04-21 07:31:28 MDT           16h Sun 2026-04-19 20:15:47 MDT           7h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Mon 2026-04-27 00:00:00 MDT        6 days Mon 2026-04-20 09:43:22 MDT     5h 29min ago zfs-snapshot-weekly.timer    zfs-snapshot-weekly.service
Mon 2026-04-27 01:09:27 MDT        6 days Mon 2026-04-20 09:43:22 MDT     5h 29min ago fstrim.timer                 fstrim.service
Mon 2026-04-27 04:28:38 MDT        6 days Mon 2026-04-20 09:43:22 MDT     5h 29min ago zpool-trim.timer             zpool-trim.service
Fri 2026-05-01 00:00:00 MDT 1 week 3 days Wed 2026-04-01 10:07:51 MDT 1 week 1 day ago zfs-snapshot-monthly.timer   zfs-snapshot-monthly.service
Fri 2026-05-01 03:17:17 MDT 1 week 3 days Wed 2026-04-01 10:07:51 MDT 1 week 1 day ago zfs-scrub.timer              zfs-scrub.service

11 timers listed.
Pass --all to see loaded but inactive timers, too.
  • Com um único comando, dá para ter a visão geral de tudo o que é executado por agenda via timers
  • list-timers faz parte da família de subcomandos do systemd usada com frequência
    • list-units também é útil
    • list-paths é um subcomando adicionado mais recentemente ao systemctl

Acordar da suspensão para executar

  • WakeSystem= permite que um timer vencido acorde o sistema do estado de suspensão
WakeSystem=
    Takes a boolean argument. If true, an elapsing timer will
    cause the system to resume from suspend, should it be
    suspended and if the system supports this.
...
  • Esse recurso é útil quando scripts importantes precisam rodar sem depender da ação física de alguém abrir a tampa do notebook
  • Em distribuições como Arch ou NixOS, que suportam baixar atualizações de pacotes antes do uso, dá para buscar os pacotes tarde da noite e deixar a atualização para a manhã, já diante do teclado
  • O manual informa que, para voltar a suspender depois que o .service terminar, é preciso colocar o sistema em suspensão novamente de forma manual

Espalhando horários de execução e mitigando thundering herd

  • O problema de thundering herd é um problema de sistema que ocorre quando muitos processos acordam ao mesmo tempo
  • Se todos os sistemas Debian do mundo estivessem configurados de forma fixa para rodar apt update às 00:00:00, a meia-noite seria um péssimo horário de pico para todo mundo
  • FixedRandomDelay= e RandomizedOffsetSec= ajudam a espalhar os horários de execução
FixedRandomDelay=
    Takes a boolean argument. When enabled, the randomized delay
    specified by RandomizedDelaySec= is chosen deterministically,
    and remains stable between all firings of the same timer,
    even if the manager is restarted. ...

RandomizedOffsetSec=
    Offsets the timer by a stable, randomly-selected, and evenly
    distributed amount of time between 0 and the specified time
    value. ...
  • Essas configurações podem ser usadas em sistemas reais que verificam atualizações de software
  • Espalhar as execuções com distribuição uniforme ajuda a reduzir o problema de thundering herd, torna o comportamento mais consistente e ajuda a evitar atividades perturbadoras, como reinicializações de daemons durante a coordenação de serviços distribuídos
  • As opções de temporização, no geral, são altamente configuráveis e oferecem controle bem granular

Compensando execuções perdidas imediatamente

  • Persistent= é especialmente adequado para scripts agendados que não devem ser pulados por causa de um notebook suspenso, mas que também não exigem WakeSystem=
Persistent=
    Takes a boolean argument. If true, the time when the service
    unit was last triggered is stored on disk. When the timer is
    activated, the service unit is triggered immediately if it
    would have been triggered at least once during the time when
    the timer was inactive. ...
  • Se um sistema com check-in agendado de gerenciamento de configuração tiver passado por indisponibilidade, basta colocar Persistent= no .timer para que ele converja ao estado correto logo após voltar a ficar online
  • Sem Persistent=, talvez seja preciso esperar até o próximo horário normal de execução do timer, e essa espera pode ser longa
  • Outros trabalhos em que não se deve esperar ao detectar uma ativação perdida incluem atualizações de sistema e verificação de jobs em lote

Cuidados ao escrever timers

  • Timers no contexto do gerenciador de usuário, administrados com systemctl --user, também são válidos, mas é preciso prestar atenção ao alvo usado em [Install]
  • Dependendo da distribuição, o alvo adequado para timers de usuário pode ser default.target
  • Assim como no cron, o aviso geral sobre manter o relógio do sistema correto continua valendo
  • Usuários do systemd podem verificar o estado da sincronização com timedatectl timesync-status
  • Muitos editores oferecem suporte nativo ao formato de arquivos de unidade do systemd, o que ajuda quando os arquivos ficam maiores
  • No Emacs, você pode usar o pacote emacs systemd

2 comentários

 
GN⁺ 2026-06-02
Comentários do Hacker News
  • Não usei timers do systemd o suficiente para rebater com firmeza, mas não entendo muito bem a afirmação de que o $PATH do cron é ambíguo
    Dá para definir PATH diretamente no crontab; não vejo por que isso seria menos previsível do que algo definido em lugares como /etc/bashrc, ~/.bashrc, ~/.profile, ~/.bash_profile, /etc/systemd/…
    Uso Linux desde 1994, mas não decoro a sintaxe do cron. Só que o comentário no crontab já traz m h dom mon dow command, então basta colocar os números conforme o cabeçalho
    Entendo o restante das reclamações e, da próxima vez que eu precisar de um job de cron, pretendo experimentar um timer do systemd

    • “Basta colocar os números conforme o cabeçalho” não resume a crítica original de forma justa, porque essa não é a sintaxe completa
      Existem vírgulas, barras, asteriscos e combinações, e se você precisar de aleatorização normalmente não dá para fazer isso só com cron, então precisa colocar dentro do comando. Escrever uma especificação de cron que não seja trivial não é fácil
    • Como alguém que já lidou com aplicações que suportam expressões cron, os números são só a parte mais básica da linguagem
      Quando alguém coloca algo como 5,3/4 4-8,11 1 4,5,6,9-11 */2, vem a diversão de tentar fazer engenharia reversa do que a pessoa realmente quis dizer, porque normalmente não é o que foi escrito
      Fica ainda mais complexo quando entram extensões suportadas só em alguns ambientes cron
      Os timers do systemd foram muito mais fáceis de administrar. Controlar se uma tarefa longa pode rodar em paralelo consigo mesma ou executar um trabalho em algum momento entre início e fim, em vez de num horário fixo, é uma grande melhoria
      Uma vez um job de backup entrou num loop de link simbólico e derrubou meu VPS, e o cron continuou disparando novos backups mesmo com o anterior ainda sem terminar
      Também era incômodo ter que reescrever comandos e scripts por causa do PATH peculiar do CRON, embora algo parecido também possa acontecer com alguns timers do systemd. Ainda assim, é possível disparar o timer manualmente sem precisar mudar o crontab para executar dali a 30 segundos e ficar esperando
    • Não quero testar jobs de cron com $PATH hardcoded no crontab
      Se eu não deixar hardcoded, o $PATH quando o cron executar será diferente do $PATH usado ao testar o comando manualmente. systemctl start foo.service inicia o comando no mesmo ambiente em que ele rodará quando o timer disparar, então dá para saber se vai se comportar da mesma forma
      Já um job de cron roda no horário definido no crontab. Timers do systemd geralmente disparam no horário marcado, mas por um bug lógico do systemd podem rodar uma vez em 29 de fevereiro e nunca mais, ou podem tanto disparar quanto não disparar quando a unidade de timer for “reiniciada”
    • A vantagem do ambiente do systemd é que ele é padronizado e quase vazio. Já o ambiente do crontab é totalmente diferente daquele herdado por scripts do supervisord ou do sysvinit, e isso já me pegou várias vezes
      No systemd, independentemente do que dispara, a unidade realmente executada é a mesma, então não existe esse descompasso
      Ainda é preciso saber qual é o ambiente padrão, mas ele é quase limpo e não sofre influência do shell. Considero isso uma vantagem do systemd
    • Eu não diria exatamente que o PATH é ambíguo, mas o cron tem problemas relacionados a PATH
      O valor padrão não inclui coisas que você esperaria, como /usr/local/bin ou /usr/sbin para root, e algumas distribuições, como Arch Linux, nem sequer mencionam no manual o caminho padrão ou recomendações de configuração
      Se você quiser adicionar um caminho só para um script específico, precisa envolver com env, configurar num script wrapper, ou mudar o caminho antes da entrada e restaurá-lo depois
      Você não pode usar ~ nem $HOME dentro de PATH, tem que escrever o caminho absoluto completo, o que é especialmente chato em crontabs de usuário
      Não é difícil contornar, mas, no geral, timers do systemd que usam por padrão o mesmo caminho que outros serviços oferecem uma experiência melhor
  • O motivo de eu ter migrado do cronie para timers do systemd foi a maior flexibilidade em relação ao horário de inicialização do sistema
    Minha estratégia de backup é criar diariamente um item de arquivo borg num horário fixo, mas o cronie exige que o sistema esteja ligado naquele momento agendado. Timers do systemd aguentam essa situação e executam o serviço assim que o sistema fica disponível
    O repositório da automação de backup é https://github.com/gchamon/borg-automated-backups

    • O Cronie tem um mecanismo para isso chamado anacron. No meu sistema, o cron chama /etc/cron.hourly/0anacron a cada hora e executa os jobs de /etc/cron.{daily,weekly,monthly} mesmo que o horário mais cedo de execução tenha sido perdido. Também dá para configurar um atraso aleatório
      Se você editar /etc/anacrontab, pode criar agendas personalizadas
      No nível de usuário, imagino que daria para colocar algo como @hourly anacron -t /path/to/anacrontab -S /path/to/spooldir no crontab do usuário, embora eu nunca tenha feito isso
      Muitas implementações de cron também têm mecanismos parecidos
    • O cron tem a opção @reboot, e eu a uso em alguns scripts; funciona bem
    • O Cronie não tem um meta-trigger @reboot?
  • Não confio muito em bicos de impressora Canon, porque se ficarem parados por um tempo podem entupir. Então pedi ao Claude para criar um script do systemd que imprimisse uma foto de cachorro toda semana, garantindo também que houvesse bastante do espectro CMYK para fazer a impressora trabalhar
    Toda segunda-feira, sentar à mesa e ver uma foto saindo da impressora de repente é uma surpresa bem agradável

    • Seria legal se a impressora tivesse um modo que, em vez de desperdiçar tinta a cada poucos dias jogando-a numa esponja, imprimisse uma imagem aleatória de um álbum ou calendário
      Pelo menos isso poderia virar uma ideia de projeto para feira de ciências das crianças
    • Meu pai tinha um modelo parecido com a Deskjet 720
      Depois que ele faleceu, ela ficou alguns anos sem uso e até desligada da tomada, mas eu precisava imprimir em cores, então só liguei na energia e mandei imprimir
      Depois de cerca de 1/5 da primeira página, todas as cores voltaram, e depois disso ela imprimiu umas 20 páginas sem problema
    • Fiz algo parecido no começo da faculdade com uma velha Samsung ML-2010
      Parecia mais um problema de software do que de hardware: se a impressora ficasse conectada ao computador e parada por mais de uma semana, ela simplesmente parava de imprimir
      Eu poderia ter investigado os logs, mas em vez disso criei uma tarefa no cron para imprimir uma página de teste toda segunda e quinta. No topo da página de teste havia só algo como LOL PRINTER WORKS
      Não era tão desperdício quanto parece. Eu fazia muitas matérias de matemática e precisava de muito papel de rascunho no verso, então usava primeiro impressões com erro ou páginas de teste antes de pegar folhas em branco
    • A resposta é impressora a laser. Só a economia com consumíveis já faz valer a pena
    • Eu ia recomendar uma impressora colorida LED barata da OKI, mas eles saíram do mercado consumidor
      A resolução máxima era só 600dpi, mas as cores eram muito boas e uniformes, e o fato de o toner não secar era o principal critério de compra do meu irmão. As inkjets da HP entupiram várias vezes
  • Gosto muito de timers do systemd. Aos poucos migrei todas as tarefas de cron que eu implantava com Ansible para timers, e agora basta copiar com o Ansible
    A integração com journalctl é especialmente boa, e em sistemas operacionais modernos onde o syslog desapareceu, como o Debian 13, isso é ainda melhor. Também é prático poder iniciar o serviço manualmente para depuração
    Quando uma tarefa de cron não funciona, acaba sendo aquela chatice de copiar e colar ou usar scripts shell extras, sem falar no buraco negro que é a saída padrão de tarefas cron
    Dá para monitorar e receber alertas de falha como com qualquer serviço systemd. Também vejo com bons olhos que projetos open source estejam recomendando cada vez mais timers como forma de implantação

    • Acho ok o projeto recomendar timers, mas só fico satisfeito se eu puder ignorar isso e usar cron
  • No NixOS, o systemd é o padrão, então ele é usado como parte de primeira classe da administração. Isso fica especialmente bom se você vem do launchd do macOS
    Também gosto do fato de que, ao distribuir ferramentas para NixOS, dá para usar o systemd de forma natural em vez de tratá-lo como um remendo improvisado
    Ainda assim, se eu estivesse distribuindo uma ferramenta com muita gestão de ciclo de vida para todos os usuários Linux, fico na dúvida sobre o que fazer, porque systemd não está em todo lugar
    Estou executando o scrub mensal de um pool btrfs com um timer do systemd. É bem útil poder decidir coisas como pular o próximo agendamento se o usuário iniciar um scrub manualmente, ou se uma tarefa mensal deve se acumular quando a máquina ficou desligada por 6 meses ou ser condensada em uma única execução

    • No NixOS, trabalhos do systemd são realmente fáceis. É melhor definir a unit em Nix do que ficar brigando com arquivos INI
      systemd.services.sync-recyclarr = { serviceConfig.Type = "oneshot"; path = [ pkgs.podman ]; script = '' podman exec -it recyclarr recyclarr sync radarr podman exec -it recyclarr recyclarr sync sonarr ''; };
      systemd.timers.sync-recyclarr = { timerConfig = { OnCalendar = "daily"; Persistent = true; Unit = "sync-recyclarr.service"; }; partOf = [ "sync-recyclarr.service" ]; requires = [ "podman-recyclarr.service" ]; wantedBy = [ "timers.target" ]; };
    • Fico curioso se você está definindo isso diretamente no arquivo flake.nix
      Eu também uso NixOS, mas mantenho toda a configuração no formato original e só crio links simbólicos com Nix. Assim fica fácil reaproveitar a configuração em sistemas non-NixOS também
      O problema é que o NixOS aparentemente não pega timers e serviços do systemd colocados na pasta ~/.config/systems/user para executar, e coisas como WantedBy=default.target também não parecem surtir efeito
      Então, depois de reiniciar manualmente todos os serviços após um reboot, acabo concordando que timers do systemd são ótimos
  • Timers podem funcionar não só com a unit de serviço de mesmo nome, mas também com units arbitrárias, o que os torna surpreendentemente flexíveis
    No meu servidor há um timer que inicia um backup.target com o ciclo completo de backup restic backup, restic prune e restic forget, incluindo horário de início aleatório e notificação toda manhã
    As units restic-* propriamente ditas são Podman Quadlet, então, desde que o servidor tenha Podman e Systemd, a configuração em si funciona independentemente do conteúdo do servidor
    Ainda assim, timers são um dos tipos de unit mais desajeitados do systemd para uso cotidiano. Entendo por que são divididos em dois arquivos e por que a sintaxe de start e enable é diferente, mas às vezes eu só queria criar um único arquivo, executar um script e pronto

    • Uso uma configuração parecida para backups. Às vezes eu desabilitava o timer para fazer outras tarefas no repositório restic, como limpar locks, e acabava sendo pego de surpresa por não perceber que a unit já disparada ainda estava rodando
    • Parece que falta uma camada de abstração acima das units do systemd. Seria bom se alguma ferramenta declarativa de linha de comando cuidasse disso, em vez de editar arquivos diretamente
      Na era dos LLMs talvez isso nem seja um grande problema, mas ainda assim parece um pouco incômodo toda vez
    • Fico curioso por que o horário do backup é aleatorizado
  • Embora eu nem sempre tenha gostado muito de certos aspectos do systemd, concordo em grande parte com essa opinião
    Para tarefas agendadas no nível do “sistema”, praticamente parei de usar cron e passei a preferir timers do systemd. Para agendamento no escopo de uma aplicação específica, também dá para usar algo como Quartz
    O motivo é meio nebuloso e difícil de explicar, mas o jeito do systemd se encaixa de forma mais limpa no meu modelo mental de “é assim que isso deveria funcionar”. Também já passei várias vezes por execuções de scripts no cron em que o PATH era ambíguo e imprevisível, embora não seja só por isso
    Eu não diria que os timers do systemd são universal e objetivamente melhores que o cron, mas pelo menos conseguiram me convencer

  • Foi uma ótima introdução aos timers do systemd, e me convenceu a finalmente experimentar
    Também gostei do list-timers. No cron, nunca foi fácil ter uma visão de todos os jobs rodando numa máquina de uma vez só. Era preciso verificar o crontab de todos os usuários, /etc/cron.d/ e os diretórios daily/hourly/monthly
    Na prática, tenho um caso de uso em que algo precisa rodar uma vez cerca de 5 minutos após o boot e depois aproximadamente a cada 12 horas, então é bom saber que os timers do systemd resolvem isso

    • Obrigado pelas palavras gentis. Num cenário em que o systemd é tão amplamente usado como hoje, sinto que realmente vale a pena aprender a usar ferramentas como systemd-analyze e systemctl list-timers
  • O systemd parece complexo à primeira vista, mas depois de usar você não quer mais usar outra coisa. É cômodo gerenciar tudo com systemctl

    • Ainda há escolhas estranhas no design que eu não entendo completamente
      Por exemplo, não entendo por que a definição de units precisa obrigatoriamente ser um arquivo real em disco. Ao recarregar o daemon, ele relê todos os arquivos, não apenas os que foram alterados. Fico pensando se não deveria existir uma API para adicionar units programaticamente. Há coisas parecidas, mas com muitas limitações e pouca flexibilidade
      Também acho estranho não ser possível declarar várias units dentro de um mesmo arquivo. Essa escolha orientada ao sistema de arquivos, sem outro nível de abstração, não parece muito inteligente. Também não segue exatamente a filosofia Unix
      Quanto ao formato de definição das units, dá a sensação de que, se TOML já existisse na época, teriam usado algo mais sensato
    • O systemd realmente tem páginas de manual úteis
    • Há quem veja de outro jeito. Depois de usar, eu fico é sem vontade de usar de novo. Eu realmente odeio o systemd
      Claro, deve ser porque eu estou velho. Evidentemente só systemd-* é o único caminho correto, e todo mundo que pensa diferente é apenas um palpiteiro
    • Ainda odeio o logging do journald
    • É uma visão bem moderna. Quando o systemd surgiu, as pessoas realmente odiavam, mas eu sempre gostei e achava que acabariam aceitando. É bom ver que isso de fato aconteceu agora
  • Uso Linux há mais de 20 anos, e systemd há mais de 10
    Mesmo assim, sempre há algo novo para aprender, e isso realmente me faz considerá-lo como mais uma ferramenta útil

    • Uso Linux há uns 30 anos e, apparently, nós passamos décadas usando cron de forma totalmente errada
 
GN⁺ 2026-06-02
Opiniões no Lobste.rs
  • O systemd não é perfeito, mas dá a sensação de que muitas decisões de design se baseiam em aprendizados obtidos com abordagens mais tradicionais do passado
    Recentemente ouvi de novo o episódio de 2015 do CRE em que Lennart Poettering explica esse contexto, e ainda hoje vale a recomendação

  • Sou do time que não gosta de systemd até os ossos, mas acho que systemd.timers é um dos conceitos “menos ruins” desse produto
    Por isso, achei meio surpreendente o autor defender isso de um jeito que parece diminuir pessoas com reclamações legítimas
    Ainda assim, gosto de usar junto com o comando at. Para comandos que devem rodar uma única vez em um horário específico, at; para o resto, timers do systemd e arquivos de unidade simples
    A melhoria que eu mais queria ver é poder saber qual usuário está executando um timer. Sou uma das poucas pessoas que ainda operam um shellbox em 2026, mas seria útil descobrir qual usuário criou um timer que fica martelando o disco a cada segundo

    • Para esse objetivo, talvez dê para usar unidades de usuário em vez de fazer todo mundo instalar timers do sistema
      Pelo que sei, com loginctl enable-linger eles podem rodar mesmo sem uma sessão de usuário ativa. Claro, talvez isso não cubra todos os casos de uso, e não conheço a situação específica
  • Eu gostaria especialmente que os timers do systemd tivessem uma barreira inicial menor no lado de gerenciamento por usuário
    Quando se olha a quantidade de configuração necessária, é realmente difícil superar crontab -e

    • A abordagem do systemd, que exige vários arquivos de configuração e serviços para configurar um único timer... como escolha de API, isso não faz sentido nenhum
  • Depois de passar muito tempo pensando em como reunir de forma organizada os logs de scripts do cron, percebi que bastava usar timers do systemd
    O problema de logging foi resolvido. Agora não tenho mais motivo para voltar a usar cron, e queria ter descoberto isso antes

    • Não bastaria mandar por pipe para logger, anexar ao arquivo de log com >> ou deixar no padrão e receber por e-mail?
  • Pode chamar de antiquado, mas ainda deixo e-mail configurado para me alcançar no servidor
    Se você automatiza isso, vem de graça em cada novo host, e no dia a dia ainda é bem conveniente
    Por exemplo, abro um multiplexador, executo long_running_process | mail root@localhost -s "done $?" e depois simplesmente esqueço

  • Bom texto, e eu também tinha um rascunho de algo parecido que precisei consultar de novo recentemente
    Se você, como eu, cair na toca do coelho do systemd, recomendo deixar os arquivos de unidade e os timers na pasta do projeto correspondente e criar links simbólicos para eles em /etc/systemd/system/
    Uma reclamação que tenho sobre o systemd é que ele não distingue as unidades instaladas pela distribuição daquelas que você mesmo escreveu, e com links simbólicos dá para manter essa separação por conta própria

    • Na verdade, essa distinção é feita pelo caminho
      Unidades de sistema/pacote/distribuição ficam em /usr/lib/systemd/system, e overrides locais ou unidades locais ficam em /etc/systemd/system