At: agendamento de tarefa única

1. Introdução ao at

O comando at é uma ferramenta do sistema Unix/Linux projetada para agendar a execução de comandos ou scripts em um horário específico, uma única vez. Diferentemente do cron, que executa tarefas repetidamente em intervalos regulares (diário, semanal, mensal), o at é ideal para situações onde você precisa executar algo apenas uma vez no futuro.

Principais diferenças entre at e cron:

Característica at cron
Frequência Única vez Recorrente
Escopo Tarefa avulsa Tarefas programadas
Gerenciamento Simples, sem arquivos de configuração Arquivos crontab
Ideal para Manutenção pontual, backups únicos Rotinas diárias, monitoramento

Pré-requisitos: O serviço atd (at daemon) precisa estar instalado e em execução. Na maioria das distribuições, você pode instalar com:

# Debian/Ubuntu
sudo apt-get install at

# RHEL/CentOS
sudo yum install at

# Ativar o serviço
sudo systemctl enable --now atd

2. Sintaxe Básica e Primeiros Passos

A estrutura fundamental do comando é:

at [opções] horário

Modo interativo: Ao executar at sem pipe, você entra em um prompt onde pode digitar comandos:

$ at 15:30
warning: commands will be executed using /bin/sh
at> echo "Tarefa executada" > /tmp/teste.log
at> date >> /tmp/teste.log
at> <Ctrl+D>
job 5 at Wed Mar 20 15:30:00 2025

Modo não interativo (recomendado): Usando pipe para passar comandos:

$ echo "echo 'Backup concluído' | mail -s 'Backup' user@example.com" | at 20:00
job 6 at Wed Mar 20 20:00:00 2025

Verificando a fila de tarefas com atq:

$ atq
5       Wed Mar 20 15:30:00 2025
6       Wed Mar 20 20:00:00 2025

3. Formatos de Horário e Data

O at aceita diversos formatos flexíveis para especificar quando executar a tarefa:

Horários absolutos:

at 14:30                    # Hoje às 14:30
at 2:30 PM                  # Hoje às 14:30 (formato AM/PM)
at 23:45                    # Hoje às 23:45

Datas específicas:

at 2025-04-15 10:00         # Formato ISO
at 04/15/25 10:00           # Formato americano
at 15.04.25 10:00           # Formato europeu

Palavras-chave especiais:

at midnight                 # 00:00 do dia atual
at noon                     # 12:00 do dia atual
at teatime                  # 16:00 (hora do chá)
at now                      # Imediatamente (útil para testes)

Expressões relativas:

at now + 30 minutes         # Daqui a 30 minutos
at now + 2 hours            # Daqui a 2 horas
at now + 1 day              # Amanhã no mesmo horário
at tomorrow                 # Amanhã à meia-noite
at next week                # Próxima semana no mesmo horário
at 10:00 + 3 days           # 3 dias a partir das 10:00 de hoje

4. Gerenciamento de Tarefas Agendadas

Listando tarefas pendentes com atq:

$ atq
7       Fri Mar 21 08:00:00 2025 a usuario
8       Sat Mar 22 12:30:00 2025 a usuario

Removendo tarefas com atrm:

$ atrm 7                    # Remove a tarefa de ID 7
$ atrm 7 8                  # Remove múltiplas tarefas

Visualizando o conteúdo de uma tarefa:

$ at -c 8
#!/bin/sh
# atrun uid=1000 gid=1000
# mail usuario 0
cd /home/usuario || {
    echo 'Erro ao acessar diretório' >&2
    exit 1
}
echo "Tarefa executada em $(date)" >> /tmp/log.txt

Gerenciamento de permissões:

O sistema utiliza dois arquivos para controlar quem pode usar o at:

  • /etc/at.allow — Lista de usuários autorizados (se existir, apenas estes podem usar)
  • /etc/at.deny — Lista de usuários proibidos (se at.allow não existir)
# Exemplo: permitir apenas usuario1 e usuario2
$ echo "usuario1" | sudo tee -a /etc/at.allow
$ echo "usuario2" | sudo tee -a /etc/at.allow

# Exemplo: negar acesso a usuario3
$ echo "usuario3" | sudo tee -a /etc/at.deny

5. Exemplos Práticos com Shell Script

Agendando um script existente com -f:

$ at now + 1 hour -f /home/usuario/scripts/backup.sh
job 9 at Wed Mar 20 16:30:00 2025

Usando variáveis de ambiente com -E:

$ export DB_HOST="localhost"
$ export DB_USER="admin"
$ at now + 30 minutes -E -f /home/usuario/scripts/backup_db.sh

Redirecionamento de saída para logs:

$ echo "/home/usuario/scripts/processar_dados.sh > /tmp/processamento.log 2>&1" | at 23:00

Múltiplos comandos em uma única tarefa:

$ cat << 'EOF' | at 03:00
#!/bin/bash
cd /home/usuario/projeto
git pull origin main
echo "Pull realizado em $(date)" >> /var/log/git_pull.log
EOF

6. Tratamento de Erros e Boas Práticas

Verificando se o serviço atd está em execução:

$ systemctl status atd
$ ps aux | grep atd
$ sudo systemctl restart atd    # Reiniciar se necessário

Lidando com falhas de agendamento:

# Verificar sintaxe do horário
$ at 25:00                      # Erro: hora inválida
garbled time

# Verificar permissões
$ at now                        # Se negado: "You do not have permission to use at."

Configurando notificações por e-mail:

Por padrão, o at envia a saída dos comandos por e-mail ao usuário que agendou. Para desabilitar:

$ echo "comando_silencioso > /dev/null 2>&1" | at now + 1 hour

Dicas de segurança:

# Sempre usar caminhos absolutos em scripts
$ echo "/usr/bin/rsync -av /origem/ /destino/" | at 02:00

# Verificar PATH dentro do script agendado
$ cat << 'EOF' | at 05:00
#!/bin/bash
export PATH="/usr/local/bin:$PATH"
/usr/local/bin/meu_script
EOF

7. Comparação com Ferramentas Alternativas

at vs. batch:

O batch é similar ao at, mas executa a tarefa apenas quando a carga do sistema está baixa:

$ echo "comando_pesado" | batch    # Executa quando a carga média < 0.8

at vs. sleep combinado com &:

# Usando sleep (menos confiável, não persiste após reboot)
$ (sleep 3600; comando) &

# Usando at (mais confiável, persiste no sistema)
$ echo "comando" | at now + 1 hour

at vs. systemd-run:

Para sistemas com systemd, é possível criar temporizadores únicos:

$ sudo systemd-run --on-active=1h /caminho/script.sh

Quando usar cada ferramenta:

  • Use at para tarefas únicas simples e rápidas
  • Use cron para tarefas recorrentes
  • Use systemd-run para integração com serviços systemd
  • Use batch para tarefas que podem esperar por baixa carga

8. Casos de Uso Avançados

Agendamento remoto via SSH:

$ echo "/usr/bin/reboot" | ssh admin@servidor "at now + 5 minutes"

Combinando at com loops em shell script:

#!/bin/bash
# Agendar 5 verificações a cada 30 minutos
for i in {1..5}; do
    echo "/usr/bin/check_status.sh" | at now + $((i * 30)) minutes
done

Wrapper em bash para simplificar o uso:

#!/bin/bash
# wrapper_at.sh - Facilita o agendamento com at
agendar() {
    local horario="$1"
    local comando="$2"
    local log="/tmp/at_$(date +%Y%m%d_%H%M%S).log"

    echo "$comando > $log 2>&1" | at "$horario"
    echo "Tarefa agendada para $horario. Log: $log"
}

# Uso
agendar "now + 2 hours" "/home/usuario/scripts/limpeza.sh"

Monitoramento e auditoria em produção:

#!/bin/bash
# monitor_at.sh - Verifica tarefas at programadas
echo "=== Tarefas Ativas em $(date) ==="
atq

echo ""
echo "=== Verificando logs recentes ==="
grep -r "atrun" /var/log/syslog | tail -5

echo ""
echo "=== Tarefas com falha nas últimas 24h ==="
find /var/spool/at -name "*.log" -mtime -1 -exec cat {} \;

Referências