Essa é uma citação do livro "Linux Command Line e Shell Scripting Bible", de Richard Blum, Christine Bresnahan pp 442, Terceira Edição, John Wiley & Filhos © 2015.
Sim, é o que diz, mas isso está errado / incompleto:
- Faltando um fechamento
fi
. - Precisa de espaço entre
[
e o seguinte'
. - É strongmente recomendado usar $ (…) em vez de
'…'
. - É importante que você use aspas em torno de expansões como
"$(…)"
- Existe um
;
adicional apósthen
Como eu sei? (bem, pela experiência ☺), mas você pode tentar Shellcheck . Cole o código do livro (depois dos asteriscos) e ele mostrará os erros listados acima, além de um "shebang ausente". Um script sem erros no Shellcheck é este:
#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
Esse site funciona porque o que foi escrito é "código shell". Essa é uma sintaxe que funciona em muitos shells.
Alguns problemas que a verificação de shell não menciona são:
-
Está assumindo que o comando date é a versão de data do GNU. Aquele com uma opção
-d
que aceitatomorrow
como um valor (busybox tem uma opção -d mas não entende amanhã e o BSD tem uma opção-d
, mas não está relacionado a "exibição" de tempo). / p> -
É melhor definir o formato após todas as opções
date -d tomorrow +'%d'
. -
A hora de início do cron é sempre na hora local, o que pode fazer com que uma tarefa seja iniciada 1 hora antes ou depois de uma contagem exata se a hora de verão for definida ou desativada.
O que fizemos foi um script de shell que pode ser chamado com o cron. Podemos modificar ainda mais o script para aceitar argumentos do programa ou comando para executar, assim (finalmente, o código correto):
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Chame esse script end_of_month.sh
e a chamada no cron é simplesmente:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Isso executaria o script end_of_month
(que internamente verificará se o dia é o último dia do mês) somente nos dias 28, 29, 30 e 31. Não é necessário verificar o final do mês em qualquer outro dia.
Verifique se o caminho correto está incluído. O PATH dentro do cron não (provavelmente) será o mesmo que o PATH do usuário.
Observe que há um script de fim de mês testado (conforme indicado abaixo) que pode chamar muitos outros utilitários ou scripts.
Isso também evitará o problema adicional que o cron gera com a linha de comando completa:
- Cron divide a linha de comando em qualquer
%
, mesmo que seja citado com'
ou"
(somente\
funciona aqui). Essa é uma maneira comum em que as tarefas do cron falham.
Você pode testar se o script end_of_month.sh
funciona corretamente em alguma data (sem esperar até o final do mês para descobrir se ele não funciona) testando-o com faketime:
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....