A maneira mais confiável de testar se uma linha crontab é válida é perguntar ao utilitário crontab
.
A maioria dos utilitários crontab
não tem uma opção para validar e não apenas alterar o crontab. Você pode chamar crontab -e
para definir o crontab e, se isso for bem-sucedido, restaurar o conteúdo anterior, mas isso não é robusto: se a entrada for válida, uma tarefa que ela contém poderá ser iniciada se o relógio passar um minuto antes você restaura o conteúdo anterior, e se alguém modificar o crontab ao mesmo tempo, uma ou ambas as operações serão interrompidas.
Então, o que você pode fazer é chamar crontab
em seu próprio playground. Uma maneira de fazer isso é executá-lo em um chroot - um verdadeiro ou falso. Você pode chamar fakechroot para criar um ambiente chroot falso sem ser root. Veja como preenchê-lo, começando por um diretório vazio:
mkdir -p bin etc tmp var/spool/cron/crontabs
echo "temp:x:$(id -u):65534:Temporary user:/:/none" >etc/password
touch var/spool/cron/crontabs
cp /usr/bin/crontab /bin/sh /bin/sleep /bin/cat bin/
cat "${cron_tab}" >input
echo n | env -i EDITOR='sleep 1; cat /input >' fakechroot -d /lib/ld-linux.so.2 -- chroot . /bin/crontab -e
Ajuste a localização dos executáveis conforme apropriado para o seu sistema. /lib/ld-linux.so.2
é o carregador dinâmico; Eu dei o local para o Linux em x86_32, use /lib64/ld-linux-x86-64.so.2
para Linux em x86_64, etc. Você pode encontrar o local executando ldd /bin/cat
e anotando aquele para o qual um único caminho absoluto é dado.
O último comando retorna 0 se o crontab for válido (ele também modifica var/spool/cron/crontabs/temp
). Ele retorna um status de erro e imprime uma mensagem de erro se o crontab for inválido.
sleep 1
garante que crontab
não pense que o arquivo não foi alterado (algumas implementações verificam o tempo de modificação e alguns sistemas de arquivos têm apenas granularidade de 1 segundo para registros de data e hora do arquivo). Para evitar o atraso, você pode copiar o utilitário touch
em vez de sleep
e organizar a alteração do registro de data e hora (se você tiver o GNU touch
)
EDITOR='f () { cat /input >"$1"; touch -d "+ 1 second" }; f'