GNU/Linux >> Tutoriales Linux >  >> Linux

Imprimir la hora actual en milisegundos o nanosegundos con printf incorporado

bash v5 y $EPOCHREALTIME

  • EPOCHREALTIME valor de coma flotante con granularidad de microsegundos

  • EPOCHSECONDS el número de segundos desde la Época Unix

Forma correcta

Simplemente:

IFS=. read ESEC NSEC <<<$EPOCHREALTIME
printf '%(%F:%T)T.%06.0f\n' $ESEC $NSEC

1. Acerca de $EPOCHREALTIME

Por favor, tenga cuidado:

    EPOCHREALTIME
         Each time this parameter is referenced, it expands to the number
         of seconds since the Unix Epoch  (see  time(3))  as  a  floating
         point  value  with  micro-second  granularity.

Entonces, si pido la misma variable dos veces en la misma línea:

echo $EPOCHREALTIME...  $EPOCHREALTIME 
1572000683.886830... 1572000683.886840

o más claramente:

printf "%s\n" ${EPOCHREALTIME#*.} ${EPOCHREALTIME#*.}
761893
761925

echo $((  -10#${EPOCHREALTIME#*.} + 10#${EPOCHREALTIME#*.} ))
37

Lo mismo en mi raspberry-pi:

printf "%s\n" ${EPOCHREALTIME#*.} ${EPOCHREALTIME#*.}
801459
801694

echo $((  -10#${EPOCHREALTIME#*.} + 10#${EPOCHREALTIME#*.} ))
246

Por lo tanto, consultar esta dos veces para construir la parte entera y la parte fraccionaria es un proceso separado podría generar problemas:(En la misma línea, acceda primero a $ EPOCHREALTIME podría dar:NNN1.999995 , luego siguiente:NNN2.000002 . El resultado será:NNN1.000002 con 1000000 error de microsegundo)

2. ¡ADVERTENCIA! Acerca de mezclar $EPOCHSECONDS y $EPOCHREALTIME

¡Usar ambos juntos no solo conduce al primer error mencionado!

$EPOCHSECONDS use llamar a time() que no se actualiza constantemente, mientras que $EPOCHREALTIME use llamar a gettimeofday() ! Por lo tanto, los resultados pueden diferir mucho:

Encontré esta respuesta a time() y gettimeofday() devuelven segundos diferentes con buena explicación.

Si pruebo en mi anfitrión:

epochVariableDiff () {
    local errcnt=0 lasterrcnt v1 v2 v3 us vals line
    while ((errcnt==0)) || ((errcnt>lasterrcnt)); do
        lasterrcnt=$errcnt
        printf -v vals '%(%s)T %s %s' -1 $EPOCHSECONDS $EPOCHREALTIME
        IFS=$' .' read v1 v2 v3 us <<<"$vals"
        [ "$v1" = "$v2" ] && [ "$v2" = "$v3" ] || ((errcnt++))
        [ $errcnt -eq 1 ] && echo "$line"
        printf -v line '%3d %s - %s - %s . %s' $errcnt $v1 $v2 $v3 $us
        printf "%s\r" "$line"
        ((errcnt)) && echo "$line"
        read -t ${1:-.0002}
    done
}

(
Nota:Yo uso read -t en lugar de sleep , porque sleep no está incorporado
Nota2:Podrías jugar con el argumento de la función para cambiar el valor del tiempo de espera de lectura (dormir)
)

Esto podría representar algo como:

$ epochVariableDiff .0002
  0 1586851573 - 1586851573 - 1586851573 . 999894
  1 1586851573 - 1586851573 - 1586851574 . 000277
  2 1586851573 - 1586851573 - 1586851574 . 000686
  3 1586851573 - 1586851573 - 1586851574 . 001087
  4 1586851573 - 1586851573 - 1586851574 . 001502
  5 1586851573 - 1586851573 - 1586851574 . 001910
  6 1586851573 - 1586851573 - 1586851574 . 002309
  7 1586851573 - 1586851573 - 1586851574 . 002701
  8 1586851573 - 1586851573 - 1586851574 . 003108
  9 1586851573 - 1586851573 - 1586851574 . 003495
 10 1586851573 - 1586851573 - 1586851574 . 003899
 11 1586851573 - 1586851573 - 1586851574 . 004400
 12 1586851573 - 1586851573 - 1586851574 . 004898
 13 1586851573 - 1586851573 - 1586851574 . 005324
 14 1586851573 - 1586851573 - 1586851574 . 005720
 15 1586851573 - 1586851573 - 1586851574 . 006113
 16 1586851573 - 1586851573 - 1586851574 . 006526
 17 1586851573 - 1586851573 - 1586851574 . 006932
 18 1586851573 - 1586851573 - 1586851574 . 007324
 19 1586851573 - 1586851573 - 1586851574 . 007733
 19 1586851574 - 1586851574 - 1586851574 . 008144

Donde parte entera de $EPOCHREALTIME podría aumentar más de 8000 microsegundos antes de $EPOCHSECONDS (en mi servidor).

Nota: Esto parece estar relacionado con algún error , el resultado puede diferir mucho entre diferentes hosts o en el mismo host después de reiniciar, y otras cosas... Extrañamente, pude reproducirlos en muchos hosts diferentes (Intel Core, Intel Xeon, Amd64...) ¡pero no en raspberry pi! ? (Mismo lanzamiento de Debian bash v5.0.3(1), versión de kernel diferente.

Correcto: ¡Esto no es un error! Mezclando time() y gettimeofday() es un error!

¡Así que evita usar ambos juntos!

3. Acerca de printf "..%06.0f"

Nota:Yo uso %06.0f en lugar de %d para asegurar $NSEC para ser interpretado como un decimal (flotante), (evitar la interpretación octal si la variable comienza por 0 ).

Comparar:

printf "nn.%06.0f\n" 012345
nn.012345

printf "nn.%06.0f\n" 098765
nn.098765

y

printf "nn.%d\n" 012345
nn.5349

printf "nn.%d\n" 098765
-bash: printf: 098765: invalid octal number
nn.0

Ejecución de muestra

Pequeña prueba:

espere hasta el próximo segundo, luego imprima la hora actual con microsegundos

while ! read -t .$((1000000-10#${EPOCHREALTIME#*.})) foo; do
    IFS=. read ESEC NSEC <<< $EPOCHREALTIME
    printf '%(%F:%T)T.%06.0f\n' $ESEC $NSEC
done

Puede finalizar esta prueba presionando Return

2019-10-25:13:16:46.000444
2019-10-25:13:16:47.000489
2019-10-25:13:16:48.000399
2019-10-25:13:16:49.000383
2019-10-25:13:16:50.000508

Linux
  1. Sincronizar la hora del servidor Linux con el servidor de hora de la red

  2. Usar colores con printf

  3. Comando para obtener el tiempo en milisegundos

  4. Obtener la hora actual en horas y minutos

  5. En Linux, cómo crear un archivo con un nombre que sea la fecha y hora actuales

Cómo obtener la fecha y hora actuales en JavaScript

Crear directorios o archivos nombrados con fecha/hora/mes/año actual

Marcas de tiempo de archivos de Linux explicadas con ejemplos

Bash Scripting - Comando Printf explicado con ejemplos

Seguimiento del tiempo con Timewarrior en la línea de comandos

Programación con cron &At