Se você busca agendar uma atividade no Linux que ocorrerá apenas uma vez, o cron pode ser considerado excessivo. A família de comandos `at` é a solução ideal! E, se a intenção é executar processos somente quando o sistema estiver com recursos ociosos, o `batch` é a ferramenta adequada.
Agendamento de Tarefas no Linux
O daemon cron gerencia uma lista de trabalhos a serem executados em horários específicos. Estes trabalhos e programas são executados em segundo plano nos momentos programados, oferecendo grande flexibilidade para agendar tarefas repetitivas. Seja uma tarefa a cada hora, em um horário específico diariamente ou uma vez por mês ou ano, o cron permite essa configuração.
Entretanto, o cron não é a melhor opção para tarefas únicas. Embora seja possível configurá-lo para tal, torna-se inconveniente lembrar de remover a entrada crontab após a execução da tarefa.
No mundo Linux, se você enfrenta um problema, é provável que outros já o tenham enfrentado também. Felizmente, devido à longa história dos sistemas operacionais Unix, é bem possível que alguém já tenha criado uma solução para seu problema.
Para o cenário descrito, a solução existe e se chama `at`.
Instalação do Comando `at`
A instalação do `at` foi necessária no Ubuntu 18.04 e no Manjaro 18.1.0, pois já estava presente no Fedora 31.
Para instalar no Ubuntu, utilize:
sudo apt-get install at
Após a instalação, inicie o daemon `at` com:
sudo systemctl enable --now atd.service
No Manjaro, instale com:
sudo pacman -Sy at
Após a instalação, inicie o daemon `at` com:
sudo systemctl enable --now atd.service
Em qualquer distribuição, use este comando para verificar se o daemon `atd` está em execução:
ps -e | grep atd
Uso Interativo do Comando `at`
Para usar o `at`, é necessário definir uma data e hora de execução. A forma de expressar essa data e hora é bastante flexível, como veremos adiante.
Mesmo no uso interativo, a data e hora devem ser fornecidas previamente. Caso contrário, o `at` responderá com “Hora distorcida”, conforme exemplificado:
at
at banana
Datas e horários podem ser explícitos ou relativos. Por exemplo, para executar um comando em um minuto, use “now” e adicione “1 minute”:
at now + 1 minute
O `at` exibe uma mensagem, um prompt e aguarda a entrada de comandos. Observe a mensagem:
Ela informa que será iniciada uma instância do shell `sh` para executar os comandos dentro dele. Seus comandos não serão executados no shell Bash, que possui um conjunto de recursos mais rico.
Se seus comandos ou scripts utilizarem funcionalidades específicas do Bash, eles podem falhar ao executar no `sh`.
Para testar se seus comandos ou scripts funcionarão em `sh`, utilize o comando:
sh
O prompt mudará para `$`, permitindo testar seus comandos. Para retornar ao shell Bash, digite:
exit
Não haverá saída padrão ou mensagens de erro dos comandos, pois o shell `sh` é executado em segundo plano, sem interface de tela.
Qualquer saída dos comandos, positiva ou negativa, será enviada por e-mail ao usuário que executou o `at`, usando o sistema de correio interno. Portanto, é necessário instalar e configurar esse sistema de e-mail.
Muitos sistemas Linux não possuem um sistema de e-mail interno, devido à pouca necessidade. Os que possuem utilizam sistemas como sendmail ou postfix. Caso seu sistema não tenha, você pode direcionar a saída para arquivos para fins de registro.
Se o comando não gerar nenhuma saída ou erro, você não receberá e-mail. Muitos comandos do Linux indicam sucesso com silêncio, portanto, em geral, você não receberá e-mail.
Para exemplificar, utilizaremos um pequeno script chamado `sweep.sh` que remove arquivos `*.bak`, `*.tmp` e `*.o`. Digite o caminho para o comando e pressione Enter:
Um novo prompt é exibido, permitindo adicionar quantos comandos desejar. Geralmente, é mais prático agrupar os comandos em um único script e chamá-lo dentro do `at`.
Use Ctrl + D para indicar o fim da inserção de comandos. O `at` exibirá `
Após a execução da tarefa, verifique seu e-mail interno com:
Se não houver e-mail, considere a execução bem-sucedida. Nesse caso, verifique se os arquivos `*.bak`, `*.tmp` e `*.o` foram removidos para confirmar a execução do comando.
Para executar novamente, utilize:
at now + 1 minute
Após um minuto, verifique novamente o e-mail:
Se houver e-mail, pressione `1` e Enter para lê-lo.
O e-mail do `at` informa que os comandos do script geraram erros. Neste exemplo, não havia arquivos para excluir porque o script os removeu na execução anterior.
Pressione D + Enter para excluir o e-mail e Q + Enter para sair do programa de e-mail.
Formatos de Data e Hora
O `at` oferece grande flexibilidade nos formatos de hora. Seguem alguns exemplos:
Executar às 11h:
at 11:00 AM
Amanhã às 11h:
at 11:00 AM tomorrow
Executar às 11h no mesmo dia da próxima semana:
at 11:00 AM next week
Executar nesse horário, neste dia, na próxima semana:
at next week
Executar às 11h na próxima sexta-feira:
at 11:00 AM next fri
Executar nesse horário na próxima sexta-feira:
at next fri
Executar às 11h nesta data, no próximo mês:
at 11:00 AM next month
Executar às 11h em uma data específica:
at 11:00 AM 3/15/2020
Executar em 30 minutos:
at now + 30 minutes
Executar em duas horas:
at now + 2 hours
Executar amanhã nesse horário:
at tomorrow
Executar nessa hora na quinta-feira:
at thursday
Executar à meia-noite:
at midnight
Executar ao meio-dia:
at noon
Para os britânicos, é possível agendar para a hora do chá (16h):
at teatime
Visualizando a Fila de Tarefas
O comando `atq` exibe a fila de trabalhos agendados:
Para cada comando na fila, o `atq` mostra:
ID do trabalho |
Data programada |
Hora programada |
Fila do trabalho (ex: “a”, “b”). Tarefas agendadas com `at` vão para a fila “a”, enquanto as de `batch` vão para “b”. |
Usuário que agendou o trabalho. |
Uso do `at` na Linha de Comando
Além do uso interativo, o `at` pode ser usado na linha de comando, facilitando seu uso em scripts.
É possível encaminhar comandos para `at` com pipes:
echo "sh ~/sweep.sh" | at 08:45 AM
O trabalho é aceito e agendado, com número e data de execução informados.
Uso do `at` com Arquivos de Comandos
É possível armazenar uma sequência de comandos em um arquivo e passá-lo para o `at`. Não precisa ser um script executável, apenas um arquivo de texto.
Use a opção `-f` (arquivo) para passar um nome de arquivo:
at now + 5 minutes -f clean.txt
O redirecionamento de arquivo também é uma opção:
at now + 5 minutes < clean.txt
Removendo Trabalhos Agendados da Fila
Para remover um trabalho da fila, use o comando `atrm`. Primeiro, use `atq` para encontrar o número do trabalho e, em seguida, use esse número com `atrm`, conforme abaixo:
atq
atrm 11
atq
Visualizando Detalhes das Tarefas
Trabalhos agendados para o futuro podem ser esquecidos. O `atq` mostra os trabalhos na fila, mas não seu conteúdo. Use a opção `-c` (cat) para visualizar detalhes de um trabalho.
Primeiro, use `atq` para encontrar o número do trabalho:
atq
Agora, use o número do trabalho (13, neste exemplo) com a opção `-c`:
at -c 13
As informações sobre o trabalho são:
Primeira linha: Indica que os comandos serão executados no shell `sh`. |
Segunda linha: Os comandos serão executados com ID de usuário e grupo 1000 (usuário que executou o comando `at`). |
Terceira linha: O usuário que receberá os e-mails sobre a execução. |
Quarta linha: A Máscara de usuário (umask) é 22. Define as permissões padrão para arquivos criados nessa sessão `sh`. A máscara é subtraída de 666, resultando em 644 (rw-r–r– em octal). |
Restante dos dados: Variáveis de ambiente. |
Resultados de um teste: Verifica se o diretório de execução pode ser acessado. Se não, gera um erro e abandona a execução. |
Comandos a serem executados: Listagem dos comandos e conteúdo dos scripts programados. O script (neste exemplo) foi escrito para ser executado em Bash, mas será executado em `sh`. |
O Comando `batch`
O comando `batch` funciona de forma semelhante ao `at`, mas com três diferenças:
Utiliza-se apenas interativamente. |
Em vez de executar em um horário específico, ele adiciona trabalhos à fila, que são executados quando a carga média do sistema é inferior a 1.5. |
Não é necessário especificar data e hora. |
Para usar o `batch`, basta chamá-lo, sem parâmetros:
batch
Em seguida, adicione as tarefas como faria com o comando `at`.
Controlando o Acesso ao Comando `at`
Os arquivos `at.allow` e `at.deny` controlam quem pode usar a família de comandos `at`. Eles estão localizados em `/etc`. Por padrão, apenas o `at.deny` existe, criado na instalação do `at`.
Seu funcionamento:
`at.deny`: Lista os usuários que não podem utilizar o `at`. |
`at.allow`: Lista os usuários que podem utilizar o `at`. Se este arquivo não existir, o `at` usa apenas o `at.deny`. |
Por padrão, todos podem usar o `at`. Para restringir o acesso, utilize o arquivo `at.allow` para listar os permitidos. É mais fácil do que adicionar todos os que não podem usar `at` ao `at.deny`.
O arquivo `at.deny`:
sudo less /etc/at.deny
Ele lista os componentes do sistema que não podem usar `at`, muitos por motivos de segurança, que não devem ser removidos.
Para editar o `at.allow`, adicione `dave` e `mary`. Somente eles terão permissão para usar `at`:
Primeiro, use:
sudo gedit /etc/at.allow
Adicione os nomes ao editor e salve o arquivo:
Se outro usuário (ex: `eric`) tentar usar o `at`:
at
Ele terá seu acesso negado:
Mesmo que `eric` não esteja no `at.deny`, ao adicionar qualquer usuário ao `at.allow`, os demais terão permissão negada.
Ideal para Tarefas Únicas
Como visto, `at` e `batch` são ideais para tarefas únicas. Para recapitular:
Use `at` para tarefas que não fazem parte do dia a dia. |
Use `batch` para tarefas que precisam ser executadas apenas quando a carga do sistema estiver baixa. |