Com some_job
definido como ( date; sleep 5; echo OK )
, você obtém quatro instâncias: uma a cada 15 segundos. Com um atraso de 20 segundos em vez de um atraso de 5 segundos (ou seja, ( date; sleep 20; echo OK )
), você obtém três instâncias iniciadas em intervalos de 20 segundos.
Seu código não funciona, e é por isso que você não pode escrever dessa maneira.
Incidentalmente, o código de Gilles também não funciona para mim (eu recebo cinco instâncias, com o último expulso antes da conclusão da quarta).
Aqui está minha opinião sobre o código. Com um trabalho de 5 segundos, recebo quatro corridas. Com um trabalho de 20 segundos, recebo duas corridas.
#!/bin/bash
#
echo START $(date)
some_job() { echo JOB BEGIN $(date); sleep 20; echo JOB END $(date); }
begin=$(date +%s)
interval=15
duration=60
while :
do
some_job
now=$(date +%s)
[[ $now -ge $((begin + duration)) ]] && break
rem=$(( (now - begin) % interval))
[[ $rem -eq 0 ]] && rem=interval
delay=$((interval - rem))
[[ $((now + delay)) -ge $((begin + duration)) ]] && break
sleep $delay
done
echo FINISH $(date)
Após a conclusão do trabalho, esse código usa o operador de módulo %
para determinar o próximo intervalo de 15 segundos. Em seguida, aguarda até que o tempo seja atingido antes de reiniciar o trabalho.