시간 경과에 따른 시간 지연을 누적하지 않고 매우 짧은 간격으로 정확하게 UNIX 명령을 실행


38

질문

오랜 시간 동안 매 초마다 정확하게 UNIX 명령을 실행할 수 있기를 바랍니다 .

명령 자체를 실행하는 데 필요한 시간 때문에 특정 시간 후에 지연되지 않는 솔루션이 필요합니다. sleep , watch 및 특정 python 스크립트는 모두 이와 관련하여 나를 실패했습니다.

http://Arduino.cc 와 같은 마이크로 컨트롤러에서는 하드웨어 클럭 인터럽트를 통해 그렇게합니다. 비슷한 시간 정확한 쉘 스크립트 솔루션이 있는지 알고 싶습니다. StackExchange.com에서 찾은 모든 솔루션은 몇 시간에 걸쳐 실행되는 경우 현저한 시간 지연을 초래했습니다. 자세한 내용은 아래를 참조하십시오.

실용 / 응용

nc1 초마다 (netcat)을 통해 타임 스탬프를 전송하여 네트워크 연결이 지속적으로 작동하는지 테스트하고 싶습니다 .

송신기:

precise-timestamp-generator | tee netcat-sender.txt | nc $receiver $port

리시버:

nc -l -p $port > netcat-receiver.txt

완료 후 두 로그를 비교하십시오.

diff netcat-sender.txt netcat-receiver.txt

차이는 전송되지 않은 타임 스탬프입니다. 이것으로 LAN / WAN / ISP가 몇시에 문제를 일으키는 지 알 수 있습니다.


솔루션 수면

while [ true ]; do date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done | tee timelog-sleep.txt

루프 내의 명령에도 약간의 시간이 걸리므로 시간이 지남에 따라 특정 오프셋을 가져옵니다.

정도

cat timelog-sleep.txt

2012-07-16 00:45:16
[...]
2012-07-16 10:20:36

경과 시간 : 34520

wc -l timelog-sleep.txt

파일 줄 : 34243

정밀성 요약 :

  • 34520-34243 = 277 타이밍 문제
  • 34520/34243 = 1.008 = 0.8 % 할인

솔루션 반복 피톤

발견 : x 초마다 유닉스 명령을 영원히 반복하십시오 .

repeat.py 1 "date '+%Y-%m-%d %H:%M:%S'" >> timelog-repeat-py.txt

시간 오프셋을 피하려고하지만 그렇게하지 않습니다.

정도

wc -l timelog-repeat-py.txt

2012-07-16 13:42:44
[...]
2012-07-16 16:45:24

경과 시간 : 10960

wc -l timelog-repeat-py.txt

파일 줄 : 10859

정밀성 요약 :

  • 10960-10859 = 101 타이밍 문제
  • 10960/10859 = 1.009 = 0.9 % 할인

솔루션 시계

watch -n 1 "date '+%Y-%m-%d %H:%M:%S' >> ~/Desktop/timelog-watch.txt"

정도

wc -l timelog-watch.txt
2012-07-16 11:04:08
[...]
2012-07-16 13:25:47

경과 시간 : 8499

wc -l timelog-watch.txt

파일 줄 : 8366

정밀성 요약 :

  • 8499-8366 = 133 타이밍 문제.
  • 8499/8366 = 1.016 = 1.6 % 할인.

5
필요한 해상도, 정확성은 무엇이며 왜 필요한가요?
jippie

nice잠이 드는 프로세스는 어떻게됩니까 ?
Tilo Wiklund

1
sleep () 호출의 지연을 최소화하기 위해 REAL TIME 스케줄링을 사용하고 있습니까?
mdpc

박스의 현재 작동 상태에 따라 타이밍이 항상 영향을 받는다는 사실이 나에게 놀랍습니다. 문제가있는 프로그램이 캐시에서 언로드되도록하는 경우 프로그램의 일반적인 런타임이 원하는 간격보다 현저히 줄어드는 것을 보장 할 수 없으면 시간이 늘어납니다. 다른 사람이 로그온하지 않은 단일 시스템 또는 단일 사용자 모드에서 실시간 시스템을 사용하고 싶습니다. 아마도 더 좋은 해결책은 문제의 프로그램을 다른 프로그램에서 호출하는 대신 루프 자체를 수행하도록 수정하는 것입니다.
Hack Saw

2
자체 스레드에서 각 명령을 실행하면 IO 관련 차단으로 인해 시간이 낭비되지 않습니다.
Joel Cornett

답변:


12

이 펄 스크립트는 어떻게 작동합니까?

#!/usr/bin/perl

use strict;
use warnings;
use Time::HiRes qw/time sleep/;

sub launch {
    return if fork;
    exec @_;
    die "Couldn't exec";
}

$SIG{CHLD} = 'IGNORE';

my $interval = shift;
my $start = time();
while (1) {
    launch(@ARGV);
    $start += $interval;
    sleep $start - time();
}

사용하다: perl timer.pl 1 date '+%Y-%m-%d %H:%M:%S'

한 번 건너 뛰지 않고 45 분 동안 실행되었으며 a) 시스템로드가 너무 높아서 fork ()가 1 초 이상 걸리거나 b) 윤초가 삽입되지 않는 한 계속 진행될 것입니다.

그러나 약간의 오버 헤드가 있기 때문에 명령이 정확한 두 번째 간격으로 실행된다고 보장 할 수는 없지만 인터럽트 기반 솔루션보다 훨씬 나쁘다는 것은 의심의 여지가 있습니다.

나는 약 1 시간 동안 date +%N(nanoseconds, GNU 확장) 실행하고 그것에 대한 통계를 실행했습니다. 가장 느린 지연 시간은 1,155 마이크로 초입니다. 평균 (산술 평균) 216µs, 중앙값 219µs, 표준 편차 42µs. 시간의 270µs 95 %보다 빠르게 실행되었습니다. 나는 C 프로그램을 제외하고는 당신이 그것을 이길 수 있다고 생각하지 않습니다.


1
1 초 간격으로 다른 활성 사용자 응용 프로그램없이 밤새 실행했으며 단일 건너 뛰기 초없이 29241 초 동안 실행되었습니다! 이것은 내 목적에 맞을 것입니다. 그럼 난, 0.1 초 간격으로 오늘 아침 다시 실행 GNU date하여 +%N: 만 3 분 후에는 해당 오류에 던진 Time::HiRes::sleep(-0.00615549): negative time not invented yet at ~/bin/repeat.pl line 23.내 저장된 스크립트에서 23 행을 :sleep $start - time();
porg

0.01 초 또는 0.001 초 간격으로 실행하면 프로그램이 "음수 시간"오류와 함께 중단 될 때까지 몇 초 이하입니다. 그러나 내 목적에 맞습니다!
porg

28

POSIX ualarm()기능을 사용하면 커널이 마이크로 초 정밀도로 프로세스에 주기적으로 신호를 보내도록 예약 할 수 있습니다.

간단한 프로그램을 준비하십시오 :

 #include<unistd.h>
 #include<signal.h>
 void tick(int sig){
     write(1, "\n", 1);
 }
 int main(){
     signal(SIGALRM, tick);
     ualarm(1000000, 1000000); //alarm in a second, and every second after that.
     for(;;)
         pause();
 }

엮다

 gcc -O2 tick.c -o tick

그런 다음 주기적으로 수행해야 할 모든 것에 첨부하십시오.

./tick | while read x; do
    date "+%Y-%m-%d %H:%M:%S"
done | tee timelog-sleep.txt

특별한 쉘이나 C-std가 필요합니까? 나는 그것을 반환했지만 (반품 누락에 대해 작은 경고를 주 었음) 출력이 생성되지 않았습니다.
math

@math를 사용 -std=c99하면 누락 된 반품에 대한 경고가 표시되지 않습니다. 그렇지 않으면 특별한 것이 필요하지 않습니다. 여분의 0을 잘못 입력 했습니까? strace ./tick시스템 콜 관점에서 무슨 일을하는지 보여줄 것입니다
Dave

gcc -O2 -std = c99 -o tick tick.c tick.c : 함수 'main'에서 : tick.c : 10 : 5 : 경고 : 함수 'ualarm'의 암시 적 선언 [-Wimplicit-function-declaration ] tick.c : 함수 'tick'에서 : tick.c : 5 : 10 : 경고 : 속성 'warn_unused_result [-Wunused-result]로 선언 된'write '의 반환 값을 무시하는 중 :: 내 시스템 (우분투 12.04)이 지원하지 않습니다. 그러나 적어도 ualarm이 unistd.h에 있어야하는 맨 페이지가 있습니다. (gcc는 4.6.3입니다)
수학

28

watch매개 변수 를 사용해 보셨습니까 --precise?

watch -n 1 --precise "date '+%Y-%m-%d %H:%M:%S.%N' >> ~/Desktop/timelog-watch.txt"

매뉴얼 페이지에서 :

일반적으로이 간격은 한 명령 실행 완료와 다음 실행 시작 사이의 시간 부족으로 해석됩니다. 그러나 -p 또는 --precise 옵션을 사용하면 매 간격마다 watch가 명령을 실행하도록 시도 할 수 있습니다. ntptime으로 시도하고 지속적으로 증가하는 일반 모드와는 달리 분수 초가 (거의) 동일하게 유지되는 방법을 확인하십시오.

그러나 시스템에서 매개 변수를 사용하지 못할 수 있습니다.

또한 프로그램 실행에 1 초 이상이 필요할 때 어떻게되는지 고려해야합니다. 다음 예약 된 실행을 건너 뛰어야합니까 아니면 늦게 실행해야합니까?

업데이트 : 스크립트를 얼마 동안 실행했는데 한 단계 만 풀지 않았습니다.

2561 lines
start: 2012-07-17 09:46:34.938805108
end:   2012-07-17 10:29:14.938547796

업데이트 :--precise 플래그가 데비안 추가되었습니다, 패치 그러나 오히려 간단하다 http://patch-tracker.debian.org/patch/series/view/procps/1:3.2.8-9squeeze1/watch_precision_time.patch


정확하게 갈 길. 이것을 +10 할 수 있기를 바랍니다.
krlmlr

watch해당 옵션 을 지원하는 버전은 무엇입니까? 내가 확인한 컴퓨터에는 없었습니다.
tylerl

Ubuntu 12.04의 현재 버전 인 0.3.0 버전입니다. procps 패키지 버전 3.2.8-11ubuntu6에서 제공됩니다.
다니엘 kullmann

흠, procps 소스 패키지는 지원하지 않습니다 --precise. 이것은 데비안 또한 (3.2.8-9, watch_precision_time.patch)입니다
다니엘 kullmann

1
문제에 대한 의견에서 mdpc와 동일하지만 시스템에 과부하가 걸리면 실패 할 수 있습니다. 방금 스트레스 (디스크 및 코어에 부하를 가함)와 함께 테스트하고 이것을 얻었습니다 2012-07-24 07:20:21.864818595 2012-07-24 07:20:22.467458430 2012-07-24 07:20:23.068575669 2012-07-24 07:20:23.968415439 . 실시간 물건 (커널 등)이 이유가 있습니다!
math

18

crontab1 분의 해상도를 갖습니다. 1 분마다 지연 시간이 누적 된 후 다음 분에 재설정하면이 기본 아이디어가 효과가 있습니다.

* * * * * for second in $(seq 0 59); do /path/to/script.sh & sleep 1s;done

참고 script.sh또한 백그라운드에서 실행됩니다. 이것은 루프가 반복 될 때마다 누적되는 지연을 최소화하는 데 도움이됩니다.

sleep그러나 지연이 얼마나 발생 하는지에 따라 다음 순간의 두 번째 0과 두 번째 59가 겹칠 가능성이 있습니다.

질문과 같은 형식으로 일부 결과를 편집 하도록 편집 하십시오.

$ cat timelog-cron
2012-07-16 20:51:01
...
2012-07-16 22:43:00

1 시간 52 분 = 6720 초

$ wc -l timelog-cron
6720 timelog-cron

0 타이밍 문제, 0 % 할인. 모든 시간 누적은 1 분마다 재설정됩니다.


1
이것이 다운 보트 된 이유를 물어봐도 될까요?
이즈 카타

2
그것은 못생긴 해킹입니다
hhaamu

2
@hhaamu 무엇에 대해 못생긴가요? PC의 범용 OS는 매우 정확한 타이밍에 중요한 작업을 위해 설계되지 않았으므로 무엇을 더 기대할 수 있습니까? "우아하고"정확하고 정확한 타이밍을 원한다면 다른 CPU 스케줄러를 사용하거나 실시간 커널로 전환하거나 전용 하드웨어 등을 사용해야합니다. 이것은 완벽한 합법적 인 솔루션이므로 다른 이유가 없습니다. 공감. cron을 통해 주기적으로 재 동기화하지 않고 "백그라운드에서 실행"된 것만 확실히 개선되었습니다.
jw013

1
게다가 멈추는 것도 쉽습니다. 사이클 도중에 죽일 위험이 없습니다. crontab에서 항목을 제거하면 분이 지나면 자체적으로 완료됩니다.
이즈 카타

시스템 cron에서 두 번째로 정확 하다는 것은 운이 좋지만 일반적으로 그렇지 않습니다 .
Dmitry Grigoryev

15

문제는 마지막 으로 잠을 잤을 때 부터 경과 한 시간을 고려하지 않고 프로그램을 실행 한 후 일정 시간 동안 자고 있다는 것입니다.

이것을 bash 또는 다른 프로그래밍 언어로 할 수 있지만, 열쇠는 다음 수면을 예약하는 시간을 결정하기 위해 시계를 사용하는 것입니다. 잠자기 전에 시계를 확인하고 남은 시간을 확인하고 차이를 자십시오.

프로세스 스케줄링 타협으로 인해 클럭 틱에서 바로 깨어날 수는 없지만 상당히 가까이 (로드되지 않은 상태에서 몇 ms 내에 또는로드 상태에서 수백 ms 내에) 있어야합니다. 또한 매 절전주기마다 재 동기화되고 누적 된 오류를 제거 할 때마다 시간이 지남에 따라 오류가 누적되지 않습니다.

클럭 틱을 정확하게 맞출 필요가 있다면 찾고있는 것은 실시간 운영 체제 이며,이 목적을 위해 정확하게 설계되었습니다.


또한 porg가 의도 한 프로세스를 실행하는 동안 블록을 테스트 한 프로그램이 실행되고있는 시스템을 죽이지 않기 위해 논리적으로 수행해야 할 가능성이 높다고 생각합니다.
symcbean

차단 여부에 관계없이 메커니즘이 제대로 작동합니다. 차단하면 차단 후 남은 시간을 잠들게됩니다. 차단하지 않으면 다른 스레드가 작동하는 동안 타이밍 스레드 또는 프로세스가 휴면 상태입니다. 어느 쪽이든 같은 결과입니다.
tylerl

@ tylerl : 솔루션에 대한 구체적인 명령 줄은 어떻게 생겼습니까?
porg

나는 당신이 @lynxlynxlynx
porg

@porg date +%S.%N초 초 정밀도로 초 수를 얻고 초 초 정밀도 usleep로 자야하는 데 사용해야하지만 그 후에는 수학의 문제입니다.
tylerl

7

나는 언제나 실행 뭔가있는에 포기했습니다 정확히 간격을. C 프로그램을 작성해야하고 자신의 코드로 1 초 간격의 부분을 초과하지 않도록 매우주의를 기울여야한다고 생각합니다. 이 작업을 수행하려면 스레딩 또는 여러 개의 상호 통신 프로세스를 사용해야합니다. 스레드 시작 또는 프로세스 시작 시간 오버 헤드가 발생하지 않도록주의하십시오.

1993 년에 관련된 것으로 보이는 한 가지 참고 문헌 : CPU 사용률 추정 및 코드 프로파일 링을위한 무작위 샘플링 클록 부록 "대적 소스 코드"에서 시간 간격을 정확하게 측정하고 "일어난"방법을 살펴보고 싶을 것입니다. 정확한 시간에 그들의 프로그램. 코드는 19 세이므로 직접 또는 쉽게 이식되지는 않지만 코드를 읽고 이해하려고하면 관련된 원칙이 코드를 안내 할 수 있습니다.

편집 : 도움이 될 수있는 또 다른 참고 자료를 찾았습니다. 대화식 및 소프트 실시간 프로세스 예약에 대한 시계 해상도의 영향 이론적 배경을 가진 데 도움이됩니다.


4

nanosleep ()을 살펴보십시오 ( http://linux.about.com/library/cmd/blcmdl2_nanosleep.htm 참조 ). 프로그램을 1 초 동안 잠자기 상태로 만드는 대신 1 초 동안 잠자기 상태로 만드십시오 (1-실행 시간). 훨씬 더 나은 해상도를 얻을 수 있습니다.


sleep예 를 들어 regular으로 동일한 작업을 수행 할 수 있습니다 sleep 0.99. 문제는 실행하는 데 걸리는 시간이 일정하지 않다는 것입니다. 평균 값이 시간이 지남에 따라 변동될 수도 있습니다.
Dmitry Grigoryev

3

백그라운드에서 명령을 실행하면 루프 타이밍에 큰 영향을 미치지 않지만, 수 밀리 초의 비용이 들기 때문에 오랜 시간 동안 누적을 원하지 않으면 충분하지 않습니다.

따라서 이것은 더 좋을 수도 있지만 여전히 충분하지 않을 수도 있습니다.

while [ true ]; do date "+%Y-%m-%d %H:%M:%S" & sleep 1; done | 
tee timelog-sleep.txt

내 컴퓨터에서 이것은 20 분 또는 분당 0.1 씩 2 오류를 발생 시켰습니다. 이는 달리기에 비해 5 배나 개선 된 것입니다.


문제 sleep 1적어도 1 초 이상 잠을 자지 못한다는 것입니다. 따라서 오류가 누적됩니다.
hahaamu

시스템에서 원래 코드를 실행하지 않고 OP와 동일한 결과를 얻지 않는 한 두 대의 다른 컴퓨터에서 타이밍 결과를 비교하는 것은 의미가 없습니다.
Dmitry Grigoryev

1

추악하지만 작동합니다. 이와 같은 루프가 필요한 경우 프로그램 디자인을 다시 생각해야합니다. 기본적으로 현재 전체 초가 이전에 확인 된 초와 동일한 지 확인하고 초가 바뀐 이후 나노초 수를 인쇄합니다. 정확도는 수면 .001의 영향을받습니다.

while true; do T=$( date +%s ); while [[ $T -eq $( date +%s ) ]]; do sleep .001; done; date "+%N nanoseconds late"; done

'페이로드' date "+%N nanoseconds late"가 1 초 미만의 시간보다 오래 걸리지 않으면 정확도는 밀리 초 입니다. 휴면 기간을 늘리거나으로 휴면 명령을 바꾸지 않아도되는 경우 CPU로드를 낮출 수 있습니다 true.

002112890 nanoseconds late
001847692 nanoseconds late
002273652 nanoseconds late
001317015 nanoseconds late
001650504 nanoseconds late
002180949 nanoseconds late
002338716 nanoseconds late
002064578 nanoseconds late
002160883 nanoseconds late

기본적으로 이벤트에 대한 CPU 폴링을 수행하고 CPU주기를 낭비하기 때문에 이는 나쁜 습관입니다. 타이머 인터럽트 (bash에서는 불가능)에 연결하거나 마이크로 컨트롤러와 같은 전용 하드웨어를 사용하고 싶을 것입니다. PC와 운영 체제는 타이밍 정확도가 높도록 설계되지 않았습니다.


1

또 다른 방법은 루프에서 일시 중단을 사용하고 정확한 외부 프로그램에서 SIGCONT를 보내는 것입니다. 신호를 보내는 것은 매우 가볍고 무언가를 실행하는 것보다 대기 시간이 훨씬 적습니다. "at"명령으로 많은 명령을 미리 큐에 넣을 수도 있습니다. 더 이상 "at"를 사용하는 사람은 거의 없습니다.

정밀도가 중요하고 이것에 대해 진지하게 생각한다면, RT-Preempt 패치 커널을 사용하여 Linux에서 수행 할 수있는 RTOS를 일반적으로 사용하는 일종의 응용 프로그램처럼 들립니다. 인터럽트 제어, 그러나 그것은 가치보다 더 귀찮을 수 있습니다.

https://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO

Xenomai도 도움이 될 수 있습니다. 전체 RTOS 구현이며 x86 및 x86_64 용으로 포팅되었지만 일부 프로그래밍이 관련되어 있습니다.

http://www.xenomai.org/index.php/Main_Page


1

ksh93(이는 부동 소수점을 갖는$SECONDS 및를 내장 sleep)

typeset -F SECONDS=0
typeset -i i=0
while true; do
   cmd
   sleep "$((++i - SECONDS))"
done

동일한 스크립트가 작동 zsh하지만 시스템 sleep명령을 호출합니다 . zshzselect내장을하지만, 1/100 해상도.


0

작은 C 프로그램을 사용합니다.

#include <sys/time.h>
#include <unistd.h>

int main(int argc, char **argv, char **envp)
{
    struct timeval start;
    int rc = gettimeofday(&start, NULL);
    if(rc != 0)
            return 1;

    for(;;)
    {
        struct timeval now;
        rc = gettimeofday(&now, NULL);
        useconds_t delay;
        if(now.tv_usec < start.tv_usec)
            delay = start.tv_usec - now.tv_usec;
        else
            delay = 1000000 - now.tv_usec + start.tv_usec;
        usleep(delay);
        pid_t pid = fork();
        if(pid == -1)
            return 1;
        if(pid == 0)
            _exit(execve(argv[1], &argv[1], envp));
    }
}

이 프로그램은 프로그램이 첫 번째 인수로 전체 경로를 호출하고 나머지 인수를 전달할 것으로 예상합니다. 명령이 완료되기를 기다리지 않으므로 행복하게 여러 인스턴스를 시작합니다.

또한, 여기에서의 코딩 스타일은 실제로 조잡하며, 적용 가능한 표준에 의해 보장되거나 보장되지 않을 수있는 많은 가정이 이루어집니다. 즉,이 코드의 품질은 "나에게 효과적"입니다.

이 프로그램은 NTP에 의해 또는 수동으로 시계를 조정하면 약간 더 길거나 짧은 간격을 갖습니다. 프로그램이이를 처리해야하는 경우 POSIX timer_create(CLOCK_MONOTONIC, ...)는 이에 영향을받지 않는 것을 제공 합니다.


0

현재 시간을 추적하고 시작 시간과 비교해야합니다. 따라서 고정 된 양이 아니라 각 반복마다 계산 된 시간을 수면합니다. 이런 식으로 타이밍 오류를 누적하지 않고 각 루프의 타이밍을 시작부터 절대 시간으로 재설정하기 때문에 원래 위치에서 벗어나지 않습니다.

또한 인터럽트가있는 경우 일부 절전 함수가 일찍 반환되므로이 경우 전체 시간이 지날 때까지 절전 메서드를 다시 호출해야합니다.



0

이것은 매우 정확한 해상도로 초당 100 회 이상 실행될 수 있습니다.

분당 루프 수의 디렉토리가 있으면 스케줄이 작성됩니다. 이 버전은 컴퓨터가 처리 할 수 ​​있다고 가정하면 마이크로 초 해상도를 지원합니다. 분당 실행 횟수는 60으로 균등하게 나눌 필요가 없으며 60으로 제한되어 6000으로 테스트했으며 작동합니다.

이 버전은 /etc/init.d 디렉토리에 설치하고 서비스로 실행할 수 있습니다.

#! /bin/sh

# chkconfig: 2345 91 61
# description: This program is used to run all programs in a directory in parallel every X times per minute. \
#              Think of this program as cron with microseconds resolution.

# Microsecond Cron
# Usage: cron-ms start
# Copyright 2014 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

# The scheduling is done by creating directories with the number of"
# executions per minute as part of the directory name."

# Examples:
#   /etc/cron-ms/7      # Executes everything in that directory  7 times a minute
#   /etc/cron-ms/30     # Executes everything in that directory 30 times a minute
#   /etc/cron-ms/600    # Executes everything in that directory 10 times a second
#   /etc/cron-ms/2400   # Executes everything in that directory 40 times a second

basedir=/etc/cron-ms

case "$1" in

   start|restart|reload)
   $0 stop
   mkdir -p /var/run/cron-ms
   for dir in $basedir/* ; do
      $0 ${dir##*/} &
   done
   exit
   ;;

   stop)
   rm -Rf /var/run/cron-ms
   exit
   ;;

esac

# Loops per minute is passed on the command line

loops=$1
interval=$((60000000/$loops))

# Just a heartbeat signal that can be used with monit to verify it's alive

touch /var/run/cron-ms

# After a restart the PIDs will be different allowing old processes to terminate

touch /var/run/cron-ms/$$

# Sleeps until a specific part of a minute with microsecond resolution. 60000000 is full minute

usleep $(( $interval - 10#$(date +%S%N) / 1000 % $interval ))

# Deleting the PID files exit the program

if [ ! -f /var/run/cron-ms/$$ ]
then
   exit
fi

# Run all the programs in the directory in parallel

for program in $basedir/$loops/* ; do
   if [ -x $program ] 
   then
      $program &> /dev/null &
   fi
done

exec $0 $loops
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.