Eu quero executar um script de shell literalmente a cada 3 dias. O uso do crontab with 01 00 */3 * *
na verdade não atende à condição, porque seria executado no dia 31 e, em seguida, novamente no 1º dia de um mês. A */3
sintaxe é o mesmo que dizer 1,4,7 ... 25,28,31.
Deve haver maneiras de fazer o próprio script verificar as condições e sair se 3 dias não se passaram. Portanto, o crontab executa o script todos os dias, mas o próprio script verifica se 3 dias se passaram.
Eu até encontrei algum código, mas ele me deu erro de sintaxe, qualquer ajuda seria apreciada.
if (! (date("z") % 3)) {
exit;
}
main.sh: line 1: syntax error near unexpected token `"z"'
main.sh: line 1: `if (! (date("z") % 3)) {'
command-line
bash
scripts
cron
Taavi
fonte
fonte
*/3
não funciona? "se 3 dias não se passaram": três dias desde o que? Por favor edite sua pergunta e esclarecer.date("z") % 3 == 0
poderia sofrer de um problema semelhante: a condição será falsa pelos quatro dias entre 29 de dezembro e 3 de janeiro, a menos que esse mês de dezembro faça parte de um ano bissexto.Respostas:
Para abortar e sair imediatamente de um script, se a última execução ainda não foi há pelo menos um tempo específico, você pode usar este método que requer um arquivo externo que armazene a data e hora da última execução.
Adicione estas linhas na parte superior do seu script Bash:
Não se esqueça de definir um valor significativo
datefile=
e adaptar o valorseconds=
às suas necessidades ($((60*60*24*3))
avalia em 3 dias).Se você não quiser um arquivo separado, também poderá armazenar o último tempo de execução no carimbo de data / hora de modificação do seu script. Isso significa, no entanto, que fazer alterações no arquivo de script redefinirá o contador 3 e será tratado como se o script estivesse sendo executado com êxito.
Para implementar isso, adicione o snippet abaixo na parte superior do seu arquivo de script:
Mais uma vez, não se esqueça de adaptar o valor
seconds=
às suas necessidades ($((60*60*24*3))
avalia em 3 dias).fonte
$[ $(date +%s) - $(< lastrun) ]
. Se o script for executado a partir do cron uma vez por dia, posso adicionar uma folga ao intervalo de tempo necessário, para que, se a execução do script for atrasada em alguns segundos, a próxima vez não pulará um dia inteiro. Ou seja, verifique todos os dias se 71 horas passaram oslt.Cron é realmente a ferramenta errada para isso. Na verdade, existe uma ferramenta comumente usada e pouco usada, na qual pode funcionar. at é projetado principalmente para uso interativo e tenho certeza de que alguém encontraria uma maneira melhor de fazer isso.
No meu caso, eu teria o script que estou executando listado em testjobs.txt e incluiria uma linha que lê.
Como exemplo, eu teria isso como testjobs.txt
Eu tenho dois comandos inocentes, que podem ser seus shellscripts. Eu corro echo para garantir uma saída determinística e data para confirmar se o comando é executado conforme necessário. Quando at executa esse comando, ele termina adicionando um novo trabalho a por 3 dias. (Eu testei com um minuto - o que funciona)
Eu tenho certeza que eu vou ser chamado pela maneira que eu abusado pelo, mas é uma ferramenta útil para agendar um comando a ser executado em um momento ou x dias após um comando anterior.
fonte
at
parece a melhor abordagem aqui. O problema dessa abordagem é que, sempre que você executa o script manualmente, adiciona outro conjunto deat
tarefas a cada três dias .at
está no topo, ou potencialmente muito mais seat
está perto do fundo de um roteiro de longa execução)Primeiro, o fragmento de código acima é uma sintaxe inválida do Bash, se parece com Perl. Segundo, o
z
parâmetro paradate
gerar o fuso horário numérico.+%j
é o número do dia. Você precisa:Mas você ainda verá estranheza no final do ano:
Você pode ter mais sorte mantendo uma contagem em um arquivo e testando / atualizando isso.
fonte
date()
função interna, mas que parece um pouco com date () em PHP (ondez
é "o dia do ano (a partir de 0)")Se você puder simplesmente deixar o script em execução perpetuamente, poderá fazer:
Esse loop é sempre verdadeiro, portanto, ele sempre executa o código e aguarda três dias antes de iniciar o loop novamente.
fonte
while true
?at
solução, isso varia conforme o tempo de execução do script a cada execução. É claro que isso pode ser contornado, economizando o tempo em que o script é iniciado e adormecendo até três dias depois.Você pode usar o anacron em vez do cron, ele foi projetado exatamente para fazer o que você precisa. Na página de manual:
fonte