Pregunta
Me gustaría poder ejecutar un comando UNIX precisamente cada segundo durante un largo período de tiempo .
Necesito una solución, que no se retrase después de un cierto tiempo, debido al tiempo que necesita el comando para ejecutarse. dormir , ver y un determinado script de Python todos me fallaron en este sentido.
En los microcontroladores, como http://Arduino.cc, lo haría a través de interrupciones de reloj de hardware.
Me gustaría saber si existe una solución similar de script de shell con precisión de tiempo. Todas las soluciones que encontré en StackExchange.com resultaron en un retraso de tiempo notable, si se ejecutaron durante horas. Ver detalles a continuación.
Propósito práctico/aplicación
Quiero probar si mi conexión de red está continuamente activa enviando marcas de tiempo a través de nc
(netcat) cada 1 segundo.
Remitente:
precise-timestamp-generator | tee netcat-sender.txt | nc $receiver $port
Receptor:
nc -l -p $port > netcat-receiver.txt
Después de completar, compare los dos registros:
diff netcat-sender.txt netcat-receiver.txt
Las diferencias serían las marcas de tiempo no transmitidas.
A partir de esto sabría a qué hora mi LAN/WAN/ISP presenta problemas.
Solución DORMIR
while [ true ]; do date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done | tee timelog-sleep.txt
Obtiene una cierta compensación con el tiempo, ya que el comando dentro del ciclo también toma un poco de tiempo.
Precisión
cat timelog-sleep.txt
2012-07-16 00:45:16
[...]
2012-07-16 10:20:36
Segundos transcurridos:34520
wc -l timelog-sleep.txt
Líneas en archivo:34243
Precisión resumida:
- 34520-34243 =277 problemas de tiempo
- 34520/34243 =1,008 =0,8 % de descuento
Solución REPETIR PYTHON
Encontrado en:Repita un comando de Unix cada x segundos para siempre
repeat.py 1 "date '+%Y-%m-%d %H:%M:%S'" >> timelog-repeat-py.txt
Se suponía que debía evitar la compensación de tiempo, pero no lo logra.
Precisión
wc -l timelog-repeat-py.txt
2012-07-16 13:42:44
[...]
2012-07-16 16:45:24
Segundos transcurridos:10960
wc -l timelog-repeat-py.txt
Líneas en archivo:10859
Precisión resumida:
- 10960-10859 =101 problemas de tiempo
- 10960/10859 =1,009 =0,9 % de descuento
Solución VER
watch -n 1 "date '+%Y-%m-%d %H:%M:%S' >> ~/Desktop/timelog-watch.txt"
Precisión
wc -l timelog-watch.txt
2012-07-16 11:04:08
[...]
2012-07-16 13:25:47
Segundos transcurridos:8499
wc -l timelog-watch.txt
Líneas en archivo:8366
Precisión resumida:
- 8499-8366 =133 problemas de tiempo.
- 8499/8366 =1,016 =1,6 % de descuento.
Respuesta aceptada:
¿Cómo funciona este script de Perl que acabo de preparar?
#!/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();
}
Usar:perl timer.pl 1 date '+%Y-%m-%d %H:%M:%S'
Ha estado funcionando durante 45 minutos sin un solo salto, y sospecho que seguirá haciéndolo a menos que a) la carga del sistema sea tan alta que fork() tarde más de un segundo o b) se inserte un segundo bisiesto.
Sin embargo, no puede garantizar que el comando se ejecute en intervalos de segundos exactos, ya que hay algo de sobrecarga, pero dudo que sea mucho peor que una solución basada en interrupciones.
Relacionado:¿Cómo saber si estoy arrancando usando UEFI?
Lo ejecuté durante aproximadamente una hora con date +%N
(nanosegundos, extensión GNU) y ejecuté algunas estadísticas al respecto. El mayor retraso que tuvo fue de 1 155 microsegundos. Promedio (media aritmética) 216 µs, mediana 219 µs, desviación estándar 42 µs. Corrió más rápido que 270 µs el 95% del tiempo. No creo que puedas vencerlo excepto con un programa en C.