Executar um script via cron a cada duas semanas

12

Eu pesquisei bastante sobre como fazer isso e vejo que não há maneira direta no cron de executar um trabalho, digamos, todas as quintas-feiras.

No momento, estou inclinado a criar um script que será executado toda semana e tocará em um arquivo "sinalizador" quando for executado, e se for executado e o arquivo já estiver lá, para remover o arquivo (e não executar o ação quinzenal).

Minha pergunta é: existe alguma outra maneira mais elegante ou mais simples de atingir esse objetivo de um script bash de ações sendo executadas a cada duas semanas automaticamente?

Obrigado!

dmkmills
fonte
1
Em vez de um arquivo de sinalizador, você pode usar os números da semana ISO. (Por exemplo,% V. Do strftime)
@ Roger: Eu presumo que você quer dizer em uma condicional dentro do script.
Pausado até novo aviso.
@ Dennis: não precisa ser (por exemplo, veja como minha resposta verifica fora do script), mas meu ponto principal é que seria muito mais simples e não exigirá nenhum estado no sistema de arquivos. No entanto, eu percebi que tem uma desvantagem semelhante como a verificação dia do mês: alguns anos tem 53 semanas e alguns têm 52.

Respostas:

11
0 0 * * Thu bash -c '(($(date +\%s) / 86400 \% 14))' && your-script

Eu costumava bash para fazer minhas contas porque sou preguiçoso; mude isso para o que quiser. Aproveito que 1º de janeiro de 1970 seja quinta-feira; para outros dias da semana, você teria que aplicar um deslocamento. Cron precisa que os sinais de porcentagem escapem.

Verificação rápida:

function check {
  when=$(date --date="$1 $(($RANDOM % 24)):$(($RANDOM % 60))" --utc)
  echo -n "$when: "
  (($(date +%s --date="$when") / 86400 % 14)) && echo run || echo skip
}

for start in "2010-12-02" "2011-12-01"; do
  for x in $(seq 0 12); do
    check "$start + $(($x * 7)) days"
  done
  echo
done

Observe que escolhi horários aleatórios para mostrar que isso funcionará se executado a qualquer momento na quinta-feira e datas escolhidas que ultrapassam os limites do ano e incluem meses com 4 e 5 quintas-feiras.

Resultado:

Thu Dec  2 06:19:00 UTC 2010: run
Thu Dec  9 23:04:00 UTC 2010: skip
Thu Dec 16 05:37:00 UTC 2010: run
Thu Dec 23 12:49:00 UTC 2010: skip
Thu Dec 30 03:59:00 UTC 2010: run
Thu Jan  6 11:29:00 UTC 2011: skip
Thu Jan 13 13:23:00 UTC 2011: run
Thu Jan 20 20:33:00 UTC 2011: skip
Thu Jan 27 16:48:00 UTC 2011: run
Thu Feb  3 17:43:00 UTC 2011: skip
Thu Feb 10 05:49:00 UTC 2011: run
Thu Feb 17 08:46:00 UTC 2011: skip
Thu Feb 24 06:50:00 UTC 2011: run

Thu Dec  1 21:40:00 UTC 2011: run
Thu Dec  8 23:24:00 UTC 2011: skip
Thu Dec 15 22:27:00 UTC 2011: run
Thu Dec 22 02:47:00 UTC 2011: skip
Thu Dec 29 12:44:00 UTC 2011: run
Thu Jan  5 17:59:00 UTC 2012: skip
Thu Jan 12 18:31:00 UTC 2012: run
Thu Jan 19 04:51:00 UTC 2012: skip
Thu Jan 26 08:02:00 UTC 2012: run
Thu Feb  2 17:37:00 UTC 2012: skip
Thu Feb  9 14:08:00 UTC 2012: run
Thu Feb 16 18:50:00 UTC 2012: skip
Thu Feb 23 15:52:00 UTC 2012: run

fonte
2
Segundos desde que a época está inerentemente no UTC, enquanto o cron é executado no horário local. Se o fuso horário do sistema não for UTC, isso causará confusão. ("Por que ele não roda? Ah, já é sexta-feira no UTC"). A existência de horário de verão torna o trabalho em torno deste muito mais difícil (embora não impossível, desde a data Cal dizer-lhe o deslocamento UTC atual)
derobert
5

Uma maneira pode ser usar o atutilitário se você estiver executando o Linux. Você pode colocar isso no final do seu script:

at X + 2 weeks -f myscript

onde X é a hora em que você deseja executar seu script. Para inicializar, basta ligar atpara o horário em que você deseja executá-lo pela primeira vez e, em seguida, a instrução acima continua renovando sua chamada agendada.

gvkv
fonte
Se isso vai ser uma solução a longo prazo i não recomendaria executar este embora a eu iria criar uma função no script que iria trabalhar para fora se ele precisa ser executado
Paul
3

Se você pode usar anacronno sistema, as coisas serão muito mais simples. Para usar, anacronvocê deve instalá-lo e também deve ter acesso root. Ele não funciona em sistemas mais antigos (como o RHEL 5.x), as versões mais antigas do ancron são executadas APENAS na inicialização. Ele funciona com sistemas mais novos (por exemplo, RHEL 6.x).

Com anacron, é possível agendar trabalhos de maneira mais flexível, por exemplo, executar o trabalho X uma vez por semana. Também anacronexecuta trabalhos quando o computador fica disponível, ou seja, você não precisa considerar quando o sistema está ativo ou inativo.

Para executar um script a cada duas semanas, você deve adicionar uma linha semelhante à seguinte ao / etc / anacrontab:

14 5 myScript script.sh

Dê uma olhada na página de manual para obter detalhes.

memin
fonte
Usar anacroné claramente a solução mais limpa da IMO (a menos que tenha algumas conseqüências indesejadas para algumas pessoas).
JanC 28/08/10
0

Não tenho certeza se existe uma maneira mais elegante de definir a cada duas semanas, mas isso pode funcionar para você.

00 06 1-7,15-21 * * test `date +\%a` = Thu && /path/to/script

Isso iniciará o script às 6:00 da manhã, na primeira e na terceira quinta-feira do mês.

pferate
fonte
2
Isso acabaria pulando uma semana, se houver um mês com três quintas-feiras, no entanto.
David Z
1
Existe um mês que tem apenas 3 quintas-feiras? Embora eu possa vê-lo pular uma semana, se houver 5 quintas-feiras. Ele pode ser atualizado para 1-7,15-21,29-31, mas seria executado consecutivamente se houvesse correspondências para o último conjunto ...
pferate
1
Às três quintas-feiras, você quis dizer três quintas-feiras que o script seria executado e não três quintas-feiras no total? Eu posso ter lido errado da primeira vez.
usar o seguinte comando
0

Eu o executava toda semana e solicitava que o script verifique se o número da semana é um número ímpar: se sim, sair.

Isso exigiria mais reflexão para funcionar de dezembro a janeiro.

Talvez o script tenha definido um arquivo de sinalizador "última execução bem-sucedida". Quando o script é iniciado, verifique se o arquivo de sinalizador foi modificado pela última vez há 14 dias.

Glenn Jackman
fonte