Esegui uno script via cron ogni due settimane


12

Ho fatto molte ricerche su come farlo, e vedo che non c'è modo diretto in cron di eseguire un lavoro, diciamo, ogni due giovedì.

In questo momento, mi sto inclinando a creare uno script che verrà eseguito ogni settimana e toccherà un file "flag" quando viene eseguito, e se viene eseguito e il file è già lì, per rimuovere il file (e non eseguire il azione bisettimanale).

La mia domanda è: esiste un altro modo più elegante o più semplice per raggiungere questo obiettivo di uno script bash di azioni eseguito ogni due settimane automaticamente?

Grazie!


1
Invece di un file flag, è possibile utilizzare i numeri delle settimane ISO. (Ad esempio, strftime's% V.)

@Roger: suppongo che intendi in un condizionale all'interno dello script.
In pausa fino a ulteriore avviso.

@Dennis: non deve essere (ad es. Vedere come la mia risposta verifica al di fuori dello script), ma il mio punto principale è che sarebbe molto più semplice e non richiederebbe alcuno stato nel filesystem. Tuttavia, mi sono reso conto che ha uno svantaggio simile al giorno del mese di controllo: alcuni anni hanno 53 settimane e alcuni hanno 52.

Risposte:


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

Ho usato bash per fare i miei calcoli perché sono pigro; passare a quello che ti piace. Approfitto del 1 ° gennaio 1970 essendo un giovedì; per gli altri giorni della settimana dovresti applicare una compensazione. Cron ha bisogno che i segni di percentuale siano fuggiti.

Controllo veloce:

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

Nota: ho scelto orari casuali per mostrare che funzionerà se eseguito in qualsiasi momento giovedì, e ho scelto date che attraversano i confini degli anni e includono mesi con 4 e 5 giovedì.

Produzione:

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

2
I secondi dall'epoca sono intrinsecamente in UTC, mentre cron viene eseguito in tempo locale. Se il fuso orario del tuo sistema non è UTC, ciò causerà confusione. ("Perché non funziona? Oh, è già venerdì in UTC"). L'esistenza dell'ora legale rende questo lavoro molto più difficile (anche se non impossibile, poiché la data ti dice l'attuale offset UTC)
derobert

5

Un modo potrebbe essere quello di utilizzare l' atutilità se stai utilizzando Linux. Potresti metterlo alla fine della tua sceneggiatura:

at X + 2 weeks -f myscript

dove X è l'ora in cui si desidera eseguire lo script. Per inizializzare basta chiamare atper il momento in cui si desidera eseguirlo la prima volta e quindi l'istruzione sopra continua a rinnovare la chiamata pianificata.


Se questa sarà una soluzione a lungo termine, non consiglierei di eseguirla anche se creerei una funzione nello script che determinerebbe se deve essere eseguita
Paul

3

Se è possibile utilizzare anacronsul sistema, le cose saranno molto più semplici. Per anacronpoterlo utilizzare è necessario averlo installato e inoltre è necessario disporre dell'accesso root. Non funziona su sistemi più vecchi (ad es. RHEL 5.x), le versioni precedenti di ancron vengono eseguite SOLO all'avvio. Funziona con i sistemi più recenti (ad esempio RHEL 6.x).

Con anacron, è possibile pianificare i lavori in modo più flessibile, ad esempio eseguire X job una volta alla settimana. anacronEsegue anche lavori quando il computer diventa disponibile, ovvero non è necessario considerare quando il sistema è attivo o inattivo.

Per eseguire uno script a settimane alterne, è necessario aggiungere una riga simile alla seguente a / etc / anacrontab:

14 5 myScript script.sh

Dai un'occhiata alla pagina man per i dettagli.


L'uso anacronè chiaramente la soluzione più pulita dell'IMO (a meno che non abbia conseguenze indesiderate per alcune persone).
JanC

0

Non sono sicuro che esista un modo più elegante per definire ogni due settimane, ma questo potrebbe funzionare per te.

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

Questo lancerà la sceneggiatura alle 6:00 del primo e terzo giovedì del mese.


2
Ciò finirebbe per saltare una settimana se c'è un mese con 3 giovedì, però.
David Z,

1
C'è un mese che ha solo 3 giovedì? Anche se posso vederlo saltare una settimana se ci sono 5 giovedì. Può essere aggiornato a 1-7,15-21,29-31, ma sarebbe eseguito back-to-back se ci fossero delle partite per l'ultimo set ...
pferate il

1
Per 3 giovedì intendevi 3 giovedì che la sceneggiatura sarebbe stata eseguita e non 3 giovedì totali? Potrei averlo letto male la prima volta.
pferate il

0

Vorrei eseguirlo ogni settimana e fare controllare lo script per vedere se il numero della settimana è un numero dispari: se sì, esci.

Ciò avrebbe bisogno di qualche pensiero in più per funzionare da dicembre a gennaio.

Forse lo script ha impostato un file flag "ultima esecuzione riuscita". All'avvio dello script, controlla che il file flag sia stato modificato l'ultima volta 14 giorni fa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.