Hai */30
nello specificatore dei minuti - ciò significa ogni minuto ma con un passo di 30 (in altre parole, ogni mezz'ora). Dal momento cron
che non passa alle risoluzioni dei sub-minuti, dovrai trovare un altro modo.
Una possibilità, sebbene sia un po 'kludge (a) , è di avere due lavori, uno sfalsato di 30 secondi:
# Need these to run on 30-sec boundaries, keep commands in sync.
* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Vedrai che ho aggiunto commenti e formattato per assicurarmi che sia facile mantenerli sincronizzati.
Entrambi i cron
posti di lavoro effettivamente eseguito ogni minuto, ma l' ultima uno aspetterà mezzo minuto prima di eseguire la "carne" del lavoro, /path/to/executable
.
Per altre cron
opzioni (non basate su), vedere le altre risposte qui, in particolare quelle che menzionano fcron
e systemd
. Questi sono probabilmente preferibili supponendo che il tuo sistema abbia la possibilità di usarli (come installare fcron
o avere una distribuzione al suo systemd
interno).
Se non si desidera utilizzare la soluzione kludgy, è possibile utilizzare una soluzione basata su loop con una piccola modifica. Dovrai comunque gestire mantenendo il processo in esecuzione in qualche forma ma, una volta ordinato, il seguente script dovrebbe funzionare:
#!/bin/env bash
# Debug code to start on minute boundary and to
# gradually increase maximum payload duration to
# see what happens when the payload exceeds 30 seconds.
((maxtime = 20))
while [[ "$(date +%S)" != "00" ]]; do true; done
while true; do
# Start a background timer BEFORE the payload runs.
sleep 30 &
# Execute the payload, some random duration up to the limit.
# Extra blank line if excess payload.
((delay = RANDOM % maxtime + 1))
((maxtime += 1))
echo "$(date) Sleeping for ${delay} seconds (max ${maxtime})."
[[ ${delay} -gt 30 ]] && echo
sleep ${delay}
# Wait for timer to finish before next cycle.
wait
done
Il trucco è usare un sleep 30
ma per avviarlo in background prima dell'esecuzione del payload. Quindi, una volta terminato il payload, attendi che lo sfondo sleep
sia terminato.
Se il payload richiede n
secondi (dove n <= 30
), l'attesa dopo il payload sarà quindi di 30 - n
secondi. Se occorrono più di 30 secondi, il ciclo successivo verrà ritardato fino al termine del carico utile, ma non più.
Vedrai che ho un codice di debug per iniziare con un limite di un minuto per rendere l'output inizialmente più facile da seguire. Aumento anche gradualmente il tempo di carico utile massimo, quindi alla fine vedrai che il carico utile supera il tempo di ciclo di 30 secondi (viene emessa una riga vuota aggiuntiva, quindi l'effetto è ovvio).
Segue una corsa di esempio (in cui i cicli iniziano normalmente 30 secondi dopo il ciclo precedente):
Tue May 26 20:56:00 AWST 2020 Sleeping for 9 seconds (max 21).
Tue May 26 20:56:30 AWST 2020 Sleeping for 19 seconds (max 22).
Tue May 26 20:57:00 AWST 2020 Sleeping for 9 seconds (max 23).
Tue May 26 20:57:30 AWST 2020 Sleeping for 7 seconds (max 24).
Tue May 26 20:58:00 AWST 2020 Sleeping for 2 seconds (max 25).
Tue May 26 20:58:30 AWST 2020 Sleeping for 8 seconds (max 26).
Tue May 26 20:59:00 AWST 2020 Sleeping for 20 seconds (max 27).
Tue May 26 20:59:30 AWST 2020 Sleeping for 25 seconds (max 28).
Tue May 26 21:00:00 AWST 2020 Sleeping for 5 seconds (max 29).
Tue May 26 21:00:30 AWST 2020 Sleeping for 6 seconds (max 30).
Tue May 26 21:01:00 AWST 2020 Sleeping for 27 seconds (max 31).
Tue May 26 21:01:30 AWST 2020 Sleeping for 25 seconds (max 32).
Tue May 26 21:02:00 AWST 2020 Sleeping for 15 seconds (max 33).
Tue May 26 21:02:30 AWST 2020 Sleeping for 10 seconds (max 34).
Tue May 26 21:03:00 AWST 2020 Sleeping for 5 seconds (max 35).
Tue May 26 21:03:30 AWST 2020 Sleeping for 35 seconds (max 36).
Tue May 26 21:04:05 AWST 2020 Sleeping for 2 seconds (max 37).
Tue May 26 21:04:35 AWST 2020 Sleeping for 20 seconds (max 38).
Tue May 26 21:05:05 AWST 2020 Sleeping for 22 seconds (max 39).
Tue May 26 21:05:35 AWST 2020 Sleeping for 18 seconds (max 40).
Tue May 26 21:06:05 AWST 2020 Sleeping for 33 seconds (max 41).
Tue May 26 21:06:38 AWST 2020 Sleeping for 31 seconds (max 42).
Tue May 26 21:07:09 AWST 2020 Sleeping for 6 seconds (max 43).
Se vuoi evitare la soluzione kludgy, probabilmente è meglio. Avrai comunque bisogno di un cron
lavoro (o equivalente) per rilevare periodicamente se questo script è in esecuzione e, in caso contrario, avviarlo. Ma lo stesso script gestisce quindi i tempi.
(a) Alcuni dei miei compagni di lavoro direbbero che i kludges sono la mia specialità :-)