Frage
Ich möchte einen UNIX-Befehl genau ausführen können jede Sekunde über einen langen Zeitraum .
Ich brauche eine Lösung, die nicht nach einer gewissen Zeit zurückbleibt, wegen der Zeit, die der Befehl selbst für die Ausführung benötigt. schlafen , ansehen , und ein bestimmtes Python-Skript alle haben mich in dieser Hinsicht versagt.
Bei Mikrocontrollern wie http://Arduino.cc würde ich das über Hardware-Clock-Interrupts machen.
Ich würde gerne wissen, ob es eine ähnliche zeitgenaue Shell-Script-Lösung gibt. Alle Lösungen, die ich in StackExchange.com gefunden habe, führten zu einer merklichen Zeitverzögerung, wenn sie über Stunden ausgeführt wurden. Einzelheiten siehe unten.
Praktischer Zweck / Anwendung
Ich möchte testen, ob meine Netzwerkverbindung kontinuierlich besteht, indem ich Zeitstempel über nc
sende (netcat) alle 1 Sekunde.
Absender:
precise-timestamp-generator | tee netcat-sender.txt | nc $receiver $port
Empfänger:
nc -l -p $port > netcat-receiver.txt
Vergleichen Sie nach Abschluss die beiden Protokolle:
diff netcat-sender.txt netcat-receiver.txt
Die Unterschiede wären die nicht übertragenen Zeitstempel.
Daraus würde ich wissen, wann mein LAN / WAN / ISP Probleme macht.
Lösung SLEEP
while [ true ]; do date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done | tee timelog-sleep.txt
Bekommt mit der Zeit einen gewissen Offset, da der Befehl innerhalb der Schleife auch etwas Zeit braucht.
Präzision
cat timelog-sleep.txt
2012-07-16 00:45:16
[...]
2012-07-16 10:20:36
Verstrichene Sekunden:34520
wc -l timelog-sleep.txt
Zeilen in der Datei:34243
Präzision zusammengefasst:
- 34520-34243 =277 Timing-Probleme
- 34520/34243 =1,008 =0,8 % Rabatt
Lösung REPEAT PYTHON
Gefunden bei:Wiederhole einen Unix-Befehl alle x Sekunden für immer
repeat.py 1 "date '+%Y-%m-%d %H:%M:%S'" >> timelog-repeat-py.txt
Soll den Zeitversatz vermeiden, tut dies aber nicht.
Präzision
wc -l timelog-repeat-py.txt
2012-07-16 13:42:44
[...]
2012-07-16 16:45:24
Verstrichene Sekunden:10960
wc -l timelog-repeat-py.txt
Zeilen in der Datei:10859
Präzision zusammengefasst:
- 10960-10859 =101 Timing-Probleme
- 10960/10859 =1,009 =0,9 % Rabatt
Lösung ansehen
watch -n 1 "date '+%Y-%m-%d %H:%M:%S' >> ~/Desktop/timelog-watch.txt"
Präzision
wc -l timelog-watch.txt
2012-07-16 11:04:08
[...]
2012-07-16 13:25:47
Verstrichene Sekunden:8499
wc -l timelog-watch.txt
Zeilen in Datei:8366
Präzision zusammengefasst:
- 8499-8366 =133 Zeitprobleme.
- 8499/8366 =1,016 =1,6 % Rabatt.
Akzeptierte Antwort:
Wie funktioniert dieses Perl-Skript, das ich mir gerade ausgedacht habe?
#!/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();
}
Verwenden Sie:perl timer.pl 1 date '+%Y-%m-%d %H:%M:%S'
Es läuft seit 45 Minuten ohne einen einzigen Sprung, und ich vermute, es wird so weitergehen, es sei denn, a) die Systemlast wird so hoch, dass fork() länger als eine Sekunde dauert, oder b) eine Schaltsekunde wird eingefügt.
Es kann jedoch nicht garantieren, dass der Befehl in genauen Sekundenintervallen ausgeführt wird, da es etwas Overhead gibt, aber ich bezweifle, dass es viel schlechter ist als eine Interrupt-basierte Lösung.
Verwandte:Woher weiß ich, ob ich mit UEFI boote?
Ich habe es etwa eine Stunde lang mit date +%N
ausgeführt (Nanosekunden, GNU-Erweiterung) und ließ einige Statistiken darüber laufen. Die größte Verzögerung betrug 1 155 Mikrosekunden. Durchschnitt (arithmetisches Mittel) 216 µs, Median 219 µs, Standardabweichung 42 µs. Es lief in 95 % der Fälle schneller als 270 µs. Ich glaube nicht, dass Sie es schlagen können, außer mit einem C-Programm.