Jalankan perintah unix tepat pada interval yang sangat singkat TANPA akumulasi jeda waktu dari waktu ke waktu


38

Pertanyaan

Saya ingin dapat menjalankan perintah UNIX tepat setiap detik selama periode waktu yang lama .

Saya membutuhkan solusi, yang tidak ketinggalan setelah waktu tertentu, karena waktu itu perintah itu sendiri perlu untuk dieksekusi. tidur , menonton , dan skrip python tertentu semua gagal saya dalam hal ini.

Pada mikrokontroler seperti http://Arduino.cc saya akan melakukan itu melalui interupsi jam hardware. Saya ingin tahu apakah ada solusi shell script tepat waktu yang serupa. Semua solusi yang saya temukan di dalam StackExchange.com, menghasilkan jeda waktu yang nyata, jika melebihi jam. Lihat detail di bawah.

Tujuan / aplikasi praktis

Saya ingin menguji apakah koneksi jaringan saya terus naik dengan mengirimkan cap waktu via nc(netcat) setiap 1 detik.

Pengirim:

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

Penerima:

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

Setelah selesai, bandingkan kedua log:

diff netcat-sender.txt netcat-receiver.txt

Difs akan menjadi cap waktu yang tidak dikirim. Dari sini saya akan tahu pada waktu apa LAN / WAN / ISP saya membuat masalah.


Solusi TIDUR

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

Mendapat offset tertentu dari waktu ke waktu, karena perintah dalam loop juga membutuhkan sedikit waktu.

Presisi

cat timelog-sleep.txt

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

Detik berlalu: 34520

wc -l timelog-sleep.txt

Baris dalam file: 34243

Presisi diringkas:

  • 34520-34243 = 277 masalah pengaturan waktu
  • 34520/34243 = 1,008 = diskon 0,8%

Solusi REPEAT PYTHON

Ditemukan di: Ulangi perintah Unix setiap x detik selamanya

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

Seharusnya menghindari waktu offset, tetapi gagal melakukannya.

Presisi

wc -l timelog-repeat-py.txt

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

Detik berlalu: 10960

wc -l timelog-repeat-py.txt

Baris dalam file: 10859

Presisi diringkas:

  • 10960-10859 = 101 masalah waktu
  • 10960/10859 = 1,009 = Diskon 0,9%

JAM TANGAN

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

Presisi

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

Detik berlalu: 8499

wc -l timelog-watch.txt

Baris dalam file: 8366

Presisi diringkas:

  • 8499-8366 = 133 masalah pengaturan waktu.
  • 8499/8366 = 1,016 = diskon 1,6%.

5
Apa resolusi yang diperlukan, akurasi dan mengapa Anda membutuhkannya / untuk apa Anda menggunakannya?
jippie

Apa yang terjadi jika Anda niceproses yang tidur?
Tilo Wiklund

1
Pernahkah Anda menggunakan penjadwalan NYATA WAKTU untuk semoga meminimalkan penundaan pada panggilan tidur ().
mdpc

Menurut saya, waktu Anda akan selalu dipengaruhi oleh kondisi pengoperasian kotak saat ini. Jika ada sesuatu yang menyebabkan program yang Anda inginkan diturunkan dari cache, Anda akan mendapatkan peningkatan waktu, kecuali Anda dapat menjamin bahwa runtime khas dari program secara signifikan kurang dari interval yang Anda inginkan. Saya ingin berada di sistem realtime, dalam pengaturan yang sangat signifikan tanpa ada orang lain yang masuk, atau dalam mode pengguna tunggal. Mungkin solusi yang lebih baik adalah dengan memodifikasi program yang dimaksud untuk melakukan loop itu sendiri, daripada memintanya dari program lain.
Hack Saw

2
Luncurkan setiap perintah di utasnya sendiri, sehingga pemblokiran terkait IO tidak membuang waktu Anda.
Joel Cornett

Jawaban:


12

Bagaimana script Perl ini saya baru saja bekerja?

#!/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();
}

Menggunakan: perl timer.pl 1 date '+%Y-%m-%d %H:%M:%S'

Ini telah berjalan 45 menit tanpa satu pun lompatan, dan saya menduga akan terus melakukannya kecuali a) beban sistem menjadi sangat tinggi sehingga fork () membutuhkan lebih dari satu detik atau b) lompatan kedua dimasukkan.

Tidak dapat menjamin, bagaimanapun, bahwa perintah berjalan pada interval kedua tepat, karena ada beberapa overhead, tetapi saya ragu itu jauh lebih buruk daripada solusi berbasis interrupt.

Saya menjalankannya sekitar satu jam dengan date +%N(nanodetik, ekstensi GNU) dan menjalankan beberapa statistik di atasnya. Kelambatan paling banyak adalah 1.155 mikrodetik. Rata-rata (rata-rata aritmatika) 216 µs, median 219 µs, standar deviasi 42 µs. Ini berjalan lebih cepat dari 270 95s 95% dari waktu. Saya tidak berpikir Anda bisa mengalahkannya kecuali dengan program C.


1
Saya menjalankannya semalaman tanpa aplikasi pengguna aktif lainnya dengan interval 1 detik, dan itu berjalan selama 29241 detik, tanpa satu detik pun terlewati! Ini akan sesuai dengan tujuan saya. Kemudian saya menjalankannya lagi pagi ini dengan interval 0,1 detik, GNU datedengan +%Ndan setelah hanya 3 menit ia melemparkan kesalahan itu: Time::HiRes::sleep(-0.00615549): negative time not invented yet at ~/bin/repeat.pl line 23.Baris 23 dalam skrip yang saya simpan:sleep $start - time();
porg

Jika Anda menjalankannya dengan interval 0,01 dtk atau 0,001 dtk, itu hanya masalah beberapa detik atau kurang sampai program dibatalkan dengan kesalahan "waktu negatif". Tetapi untuk tujuan saya itu cocok!
porg

28

Fungsi POSIX ualarm()memungkinkan Anda menjadwalkan kernel untuk memberi sinyal secara berkala pada proses Anda, dengan presisi mikrodetik.

Menyiapkan program sederhana:

 #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();
 }

Menyusun

 gcc -O2 tick.c -o tick

Kemudian tempelkan pada apa pun yang perlu Anda lakukan secara berkala seperti:

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

Apakah saya memerlukan shell khusus atau C-std untuk itu? Saya telah mengkompilasinya (yang memberikan peringatan kecil tentang pengembalian yang hilang) tetapi tidak ada output yang dihasilkan.
matematika

@math With -std=c99, Anda tidak akan mendapatkan peringatan tentang pengembalian yang hilang. Kalau tidak, Anda tidak perlu sesuatu yang istimewa. Apakah Anda salah mengetik nol ekstra? strace ./tickakan menunjukkan kepada Anda apa yang dilakukannya dari perspektif syscall
Dave

Saya mendapatkan: gcc -O2 -std = c99 -o tick tick.c tick.c: Dalam fungsi 'main': tick.c: 10: 5: peringatan: deklarasi implisit fungsi 'ualarm' [-Wimplicit-function-declaration ] tick.c: Dalam fungsi 'tick': tick.c: 5: 10: peringatan: mengabaikan nilai balik 'write', dideklarasikan dengan atribut warn_unused_result [-Wunused-result] :: Sepertinya sistem saya (Ubuntu 12.04) tidak tidak mendukungnya. Namun setidaknya ada halaman manual bahwa ualarm harus di unistd.h. (gcc adalah 4.6.3)
matematika

28

Sudahkah Anda mencoba watchparameternya --precise?

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

Dari halaman manual:

Biasanya, interval ini diartikan sebagai jarak waktu antara selesainya satu perintah dan awal dari proses selanjutnya. Namun, dengan opsi -p atau --precise, Anda dapat melakukan arloji untuk menjalankan perintah setiap interval detik. Cobalah dengan ntptime dan perhatikan bagaimana detik pecahan tetap (hampir) sama, sebagai lawan dari mode normal di mana mereka terus meningkat.

Parameternya mungkin tidak tersedia di sistem Anda.

Anda juga harus mempertimbangkan apa yang harus terjadi ketika pelaksanaan program Anda membutuhkan lebih dari satu detik. Haruskah eksekusi yang dijadwalkan berikutnya dilewati, atau harus terlambat?

Pembaruan : Saya menjalankan skrip untuk beberapa waktu, dan tidak kehilangan satu langkah pun:

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

Memperbarui: The --precisebendera adalah tambahan Debian, patch Namun agak sederhana: http://patch-tracker.debian.org/patch/series/view/procps/1:3.2.8-9squeeze1/watch_precision_time.patch


Cara yang tepat untuk pergi. Seandainya saya bisa memberi +10 ini.
krlmlr

Versi mana yang watchmendukung opsi itu? Itu tidak ada pada mesin yang saya periksa.
tylerl

Versi 0.3.0, yang merupakan versi saat ini di Ubuntu 12.04. Itu berasal dari versi 3.2.8-11ubuntu6 dari paket procps.
daniel kullmann

Hmm, paket source procps tidak mendukung --precise. Ini adalah tambahan Debian (3.2.8-9, watch_precision_time.patch)
daniel kullmann

1
Ok, tetapi sama dengan mdpc dalam komentar pada pertanyaan yang dinyatakan: Ini mungkin juga gagal ketika sistem Anda sedang di bawah beban berat. Saya baru saja mengujinya bersamaan dengan stres (meletakkan beban pada disk dan inti) dan mendapatkan ini: 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 Hal-hal waktu nyata (kernel dll) ada di luar sana karena suatu alasan!
matematika

18

crontabmemiliki resolusi 1 menit. Jika Anda baik-baik saja dengan akumulasi waktu jeda per menit itu dan kemudian mengatur ulang pada menit berikutnya, ide dasar ini bisa bekerja:

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

Perhatikan bahwa script.shini juga dijalankan di latar belakang. Ini akan membantu meminimalkan kelambatan yang terakumulasi dengan setiap iterasi dari loop.

Bergantung pada berapa banyak lag yang sleepdihasilkan, ada kemungkinan 59 detik tumpang tindih dengan 0 kedua pada menit berikutnya.

EDIT untuk melemparkan beberapa hasil, dalam format yang sama seperti pada pertanyaan:

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

1 jam 52 menit = 6720 detik

$ wc -l timelog-cron
6720 timelog-cron

0 masalah waktu, diskon 0%. Setiap akumulasi waktu disetel ulang setiap menit.


1
Bolehkah saya bertanya mengapa ini diturunkan?
Izkata

2
Ini peretasan yang buruk
hhaamu

2
@hhaamu Ada apa dengan ini? Tujuan umum OS pada PC tidak dirancang untuk operasi kritis-waktu yang sangat tepat, jadi apa lagi yang bisa Anda harapkan? Jika Anda ingin "elegan" dan waktu yang sangat tepat, Anda harus menggunakan penjadwal CPU yang berbeda, atau beralih ke kernel waktu nyata, atau menggunakan perangkat keras khusus, dll. Ini adalah solusi yang sangat sah dan saya tidak melihat alasan untuk setiap downvotes. Ini tentu merupakan perbaikan dari yang hanya memiliki "run in background" tanpa sinkronisasi ulang secara berkala melalui cron.
jw013

1
Plus menghentikannya mudah. Tidak perlu mengambil risiko membunuhnya di tengah siklus - menghapus entri dari crontab dan selesai sendiri pada akhir menit.
Izkata

Anda hanya beruntung bahwa pada sistem Anda crontepat untuk yang kedua, tetapi tidak demikian halnya secara umum.
Dmitry Grigoryev

15

Masalah Anda adalah bahwa Anda tidur dalam jumlah waktu yang tetap setelah Anda menjalankan program Anda tanpa mempertimbangkan jumlah waktu yang telah berlalu sejak terakhir kali Anda tidur.

Anda dapat melakukannya dengan bash atau bahasa pemrograman lainnya, tetapi kuncinya adalah menggunakan jam untuk menentukan berapa lama untuk menjadwalkan tidur berikutnya. Sebelum Anda tidur, periksa jam, lihat berapa banyak waktu yang tersisa, dan tidur perbedaannya.

Karena kompromi penjadwalan proses, Anda tidak dijamin untuk bangun tepat pada centang jam, tetapi Anda harus cukup dekat (dalam beberapa ms dibongkar, atau dalam beberapa ratus ms dalam pemuatan). Dan Anda tidak akan menumpuk kesalahan dari waktu ke waktu karena setiap kali Anda menyinkronkan ulang pada setiap siklus tidur dan menghapus setiap kesalahan yang terakumulasi.

Jika Anda perlu menekan tanda centang jam tepat, maka apa yang Anda cari adalah sistem operasi waktu nyata , yang dirancang persis untuk tujuan ini.


Saya pikir itu juga sangat mungkin bahwa program porg telah menguji blok saat menjalankan proses yang dimaksud - yang secara logis harus mereka lakukan untuk menghindari membunuh mesin yang sedang mereka jalankan.
symcbean

Apakah Anda memblokir atau tidak, mekanismenya bekerja dengan baik. Jika Anda memblokir, Anda tidur waktu yang tersisa setelah memblokir. Jika Anda tidak memblokir, maka utas waktu atau proses Anda sedang tidur sementara yang lain bekerja. Either way, hasil yang sama.
tylerl

@tylerl: Bagaimana baris perintah konkret terlihat seperti untuk solusi Anda?
porg

Saya kira maksud Anda sama seperti @lynxlynxlynx
porg

@porg, Anda perlu menggunakan date +%S.%Nuntuk mendapatkan jumlah detik dengan ketepatan sub-detik, dan usleepuntuk tidur dengan ketepatan sub-detik, tetapi setelah itu hanya soal matematika.
tylerl

7

Saya selalu menyerah untuk menjalankan sesuatu tepat pada interval. Saya pikir Anda harus menulis program C, dan memperhatikan dengan sangat hati-hati untuk tidak melebihi porsi interval 1 detik dengan kode Anda sendiri. Anda mungkin harus menggunakan proses threading atau multipel, antar-komunikasi untuk membuatnya bekerja. Berhati-hatilah untuk menghindari overhead yang memulai thread atau memulai proses.

Salah satu referensi yang tampaknya tanggal relevan dengan 1993: Sebuah Acak Sampling Jam untuk Estimasi CPU Pemanfaatan dan Kode Profiling Anda akan ingin lihat lampiran "Musuh Source Code" untuk melihat bagaimana mereka diukur secara akurat interval waktu, dan "bangun" program mereka pada waktu yang tepat. Karena kode ini berumur 19 tahun, mungkin kode itu tidak akan port langsung atau mudah, tetapi jika Anda membacanya dan mencoba memahaminya, prinsip-prinsip yang terlibat mungkin memandu kode Anda.

EDIT: Menemukan referensi lain yang mungkin membantu: Efek Resolusi Jam pada Penjadwalan Proses Interaktif dan Soft Real-Time Yang seharusnya membantu Anda dengan latar belakang teoritis.


4

Lihatlah nanosleep () (dari http://linux.about.com/library/cmd/blcmdl2_nanosleep.htm ). Alih-alih membuat program Anda tidur 1 detik, buatlah tidur (1 - jumlah yang diperlukan untuk menjalankan) detik. Anda akan mendapatkan resolusi yang jauh lebih baik.


Anda dapat melakukan hal yang sama dengan biasa sleep, yaitu sleep 0.99. Masalahnya adalah bahwa jumlah waktu yang diperlukan untuk menjalankan jauh dari konstan, bahkan nilai rata-rata dapat berfluktuasi dari waktu ke waktu.
Dmitry Grigoryev

3

Coba jalankan perintah Anda di latar belakang sehingga tidak terlalu mempengaruhi timing loop, tetapi bahkan itu tidak akan cukup jika Anda tidak ingin ada akumulasi untuk jangka waktu yang lama karena pasti ada beberapa milidetik biaya yang terkait dengannya.

Jadi, ini sepertinya lebih baik, tetapi juga kemungkinan masih belum cukup baik:

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

Di komputer saya ini memberikan 2 kesalahan dalam 20 menit atau 0,1 per menit, yang merupakan peningkatan lima kali lipat lebih rendah selama Anda menjalankan.


Masalahnya sleep 1adalah dijamin tidur setidaknya satu detik - tidak pernah kurang. Karenanya kesalahan terakumulasi.
hhaamu

Membandingkan hasil penghitungan waktu dari dua komputer yang berbeda tidak ada artinya, kecuali Anda telah menjalankan kode asli pada sistem Anda dan memperoleh hasil yang sama dengan OP.
Dmitry Grigoryev

1

Jelek tapi berhasil. Anda mungkin harus memikirkan kembali desain program Anda jika Anda memerlukan loop seperti ini. Ini pada dasarnya memeriksa apakah seluruh detik saat ini sama dengan yang diperiksa sebelumnya dan mencetak jumlah nanodetik sejak pergantian detik. Akurasi dipengaruhi oleh tidur 0,001.

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

Akurasi dalam milidetik, asalkan 'payload' date "+%N nanoseconds late"tidak memakan waktu lebih lama dari hanya di bawah satu detik. Anda dapat menurunkan beban CPU dengan menambah periode tidur atau jika Anda benar-benar tidak keberatan cukup ganti perintah tidur dengan 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

Ini adalah praktik buruk karena pada dasarnya Anda membuat jajak pendapat CPU untuk suatu acara dan Anda membuang-buang siklus CPU. Anda mungkin ingin melampirkan penghenti waktu (tidak mungkin dari bash) atau menggunakan perangkat keras khusus seperti mikrokontroler. PC dan sistem operasinya tidak dirancang untuk akurasi pengaturan waktu yang tinggi.


1

Metode lain adalah dengan menggunakan penangguhan dalam satu lingkaran dan mengirim SIGCONT dari program eksternal yang tepat. Mengirim sinyal sangat ringan dan memiliki latensi jauh lebih sedikit daripada mengeksekusi sesuatu. Anda juga dapat melakukan pra-antrian sekelompok perintah dengan perintah "at", hampir tidak ada yang menggunakan "at" lagi saya tidak yakin seberapa tepat itu.

Jika presisi sangat penting dan Anda ingin serius tentang ini, ini terdengar seperti jenis aplikasi di mana Anda biasanya akan menggunakan RTOS, yang dapat dilakukan di Linux dengan RT-Preempt patched kernel, yang akan memberi Anda presisi dan beberapa ukuran kontrol interupsi, tetapi mungkin lebih mengganggu daripada nilainya.

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

Xenomai juga mungkin membantu, ini adalah implementasi RTOS penuh dan porting untuk x86 dan x86_64, tetapi ada beberapa pemrograman yang terlibat.

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


1

Dengan ksh93(yang memiliki titik apung $SECONDSdan builtin sleep)

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

Script yang sama akan bekerja dengan zshbaik tetapi akan menjalankan sleepperintah sistem Anda . zshmemiliki zselectbuiltin, tetapi dengan resolusi 1/100 saja.


0

Saya akan pergi dengan program C kecil:

#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));
    }
}

Program ini mengharapkan program untuk memanggil dengan jalur penuh sebagai argumen pertama, dan meneruskan argumen yang tersisa. Itu tidak akan menunggu perintah selesai, jadi ia akan dengan senang hati memulai beberapa contoh.

Juga, gaya pengkodean di sini benar-benar ceroboh, dan sejumlah asumsi dibuat yang mungkin atau mungkin tidak dijamin oleh standar yang berlaku, yaitu kualitas kode ini "berfungsi untuk saya".

Program ini akan mendapatkan interval yang agak lebih lama atau lebih pendek ketika jam disesuaikan dengan NTP atau dengan mengaturnya secara manual. Jika program harus menangani ini, POSIX menyediakan timer_create(CLOCK_MONOTONIC, ...)yang tidak terpengaruh oleh ini.


0

Anda harus melacak waktu saat ini dan membandingkannya dengan waktu mulai. Jadi Anda tidur dengan jumlah waktu yang dihitung setiap iterasi, bukan jumlah yang tetap. Dengan cara ini Anda tidak akan mengakumulasi kesalahan waktu dan bergeser dari tempat Anda seharusnya karena Anda mengatur ulang waktu Anda setiap loop ke waktu absolut dari awal.

Juga beberapa fungsi tidur kembali lebih awal jika ada interupsi, jadi dalam hal ini Anda harus memanggil metode tidur Anda lagi sampai waktu penuh telah berlalu.



0

Yang ini dapat berjalan setidaknya 100 kali per detik dengan resolusi yang sangat akurat.

Keberadaan direktori jumlah loop per menit menciptakan jadwal. Versi ini mendukung resolusi microsecond dengan anggapan komputer Anda dapat mengatasinya. Jumlah eksekusi per menit tidak harus dibagi rata dengan 60 atau terbatas pada 60 Saya telah mengujinya hingga 6000 dan berfungsi.

Versi ini dapat diinstal di direktori /etc/init.d dan dijalankan sebagai layanan.

#! /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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.