존재하다https://unix.stackexchange.com/a/11105/674, Giles는 다음과 같이 썼습니다.
다음 crontab 줄은
some_job
15초마다 시작됩니다.* * * * * for i in 0 1 2; do some_job & sleep 15; done; some_job
스크립트에서는 작업이 15초 이상 걸리지 않을 것으로 가정합니다. 다음 약간 더 복잡한 스크립트는 시간이 너무 오래 걸릴 경우 다음 인스턴스를 실행하지 못하게 합니다.
date
지원되는%s
형식(GNU 또는 Busybox 등) 에 의존하므로 Linux에서는 문제가 없습니다. crontab에 직접 입력하는 경우%
crontab 줄에 나타나는 대로 문자를 작성해야 합니다.\%
end=$(($(date +%s) + 45)) while true; do some_job & [ $(date +%s) -ge $end ] && break sleep 15 wait done [ $(date +%s) -ge $(($end + 15)) ] || some_job
그러나 15초마다 작업을 실행해야 한다면 cron이 아마도 잘못된 접근 방식일 수 있다는 점을 지적하고 싶습니다. unice는 수명이 짧은 프로세스에 적합하지만 15초마다 프로그램을 시작하는 오버헤드는 무시할 수 없을 정도입니다(프로그램 요구 사항에 따라 다름). 애플리케이션을 계속 실행하고 15초마다 작업을 수행하도록 할 수는 없나요?
이 올바른지
이 스크립트는 cron으로 실행하면 안 됩니다.
이 스크립트는 지금부터 15초마다 실행되는 "some_job" 인스턴스를 제출하려고 시도하며 "some_job"을 실행하는 인스턴스가 이미 있는 경우 "some_job"의 다음 인스턴스가 제출되지 않도록 방지합니다.
break
1분 내 45~59초 사이에 "some_job" 인스턴스가 처음 제출되면 스크립트가 실행됩니다. 그런 다음 스크립트는 while 루프에서 벗어나 건너뛰고 sleep
인스턴스 wait
실행이 완료되도록 합니다. 루프 외부의 다음 명령에서는 조건이 false가 되며(시간이 여전히 분당 45~59초이기 때문에) 스크립트는 "some_job"의 마지막 인스턴스를 제출합니다. 이제 "some_job" 인스턴스가 두 개 실행되고 있는데 이는 바람직하지 않습니다. 옳은?
이렇게 스크립트를 작성하면 어떨까요?
end=$(($(date +%s) + 60))
while true; do
some_job &
sleep 15
wait
[ $(date +%s) -ge $end ] && break
done
감사해요.
답변1
some_job
설정을 사용하면 ( date; sleep 5; echo OK )
15초마다 하나씩 총 4개의 인스턴스가 생성됩니다. 5초 지연(즉) 대신 20초 지연을 사용하면 ( date; sleep 20; echo OK )
20초 간격으로 3개의 인스턴스를 시작할 수 있습니다.
귀하의 코드가 작동하지 않기 때문에 그런 식으로 작성할 수 없습니다.
그런데 Giles의 코드가 나에게도 작동하지 않습니다. (5개의 인스턴스가 있고 마지막 인스턴스는 네 번째 인스턴스가 완료되기 전에 시작됩니다.)
이것이 제가 생각하는 코드입니다. 5초의 작업으로 4번의 실행을 얻었습니다. 20초의 작업으로 두 번의 실행을 얻었습니다.
#!/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)
작업이 완료된 후 이 코드는 모듈로 연산자를 사용하여 %
다음 15초 간격을 결정합니다. 그런 다음 작업을 다시 시작하기 전에 해당 시간에 도달할 때까지 기다립니다.