GNU/Linux >> Tutoriels Linux >  >> Linux

Impression de l'heure actuelle en millisecondes ou nanosecondes avec printf intégré

bash v5 et $EPOCHREALTIME

  • EPOCHREALTIME valeur à virgule flottante avec une granularité à la microseconde

  • EPOCHSECONDS le nombre de secondes depuis l'époque Unix

Bonne manière

Simplement :

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

1. À propos de $EPOCHREALTIME

Veuillez prendre soin :

    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.

Donc, si je demande la même variable deux fois dans la même ligne :

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

ou plus clairement :

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

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

Idem sur mon raspberry-pi :

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

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

Donc, demander ces deux temps pour construire la partie entière et la partie fractionnaire est un processus séparé pourrait entraîner des problèmes :(sur la même ligne, premier accès à $ EPOCHREALTIME pourrait donner :NNN1.999995 , puis suivant :NNN2.000002 . Le résultat deviendra :NNN1.000002 avec 1000000 erreur de micro-seconde)

2. ATTENTION! À propos du mélange $EPOCHSECONDS et $EPOCHREALTIME

L'utilisation des deux ensemble ne conduit pas seulement au premier bogue mentionné !

$EPOCHSECONDS utiliser l'appel au time() qui n'est pas mis à jour en permanence, tandis que $EPOCHREALTIME utiliser l'appel au gettimeofday() ! Les résultats peuvent donc être très différents :

J'ai trouvé cette réponse à time() et gettimeofday() renvoient des secondes différentes avec une bonne explication.

Si j'essaie sur mon hébergeur :

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
}

(
Remarque :j'utilise read -t au lieu de sleep , car sleep n'est pas intégré
Nota2 :vous pouvez jouer avec l'argument de la fonction pour modifier la valeur du délai de lecture (veille)
)

Cela pourrait rendre quelque chose de simple :

$ 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

Où partie entière de $EPOCHREALTIME pourrait augmenter de plus de 8 000 microsecondes avant $EPOCHSECONDS (sur mon hébergeur).

Remarque : Cela semble être lié à un bogue , le résultat peut différer beaucoup entre différents hôtes ou sur le même hôte après le redémarrage, et d'autres choses... Étrangement, je pourrais les reproduire sur de nombreux hôtes différents (Intel Core, Intel Xeon, Amd64..) mais pas sur raspberry pi ! ? (Même Debian bash v5.0.3(1)-release), version différente du noyau.

Correct : Ce n'est pas un bug! Mélange time() et gettimeofday() est un bug !

Alors évitez d'utiliser les deux ensemble !!!

3. À propos de printf "..%06.0f"

Remarque :j'utilise %06.0f au lieu de %d pour assurer $NSEC à interpréter comme un nombre décimal (flottant), (empêcher l'interprétation octale si la variable commence par 0 ).

Comparez :

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

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

et

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

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

Échantillon exécuté

Petit essai :

attendez la seconde suivante, puis imprimez l'heure actuelle avec des micro-secondes

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

Vous pouvez terminer ce test en appuyant sur Retour

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. Synchroniser l'heure du serveur Linux avec le serveur de temps réseau

  2. Date en millisecondes sur Openwrt sur Arduino Yun ?

  3. Heure de début du processus avec fuseau horaire ?

  4. Utilisation des couleurs avec printf

  5. Comment imprimer l'heure actuelle (avec millisecondes) en utilisant C++ / C++11

Comment obtenir la date et l'heure actuelles en JavaScript

Créer des répertoires ou des fichiers nommés avec la date/l'heure/le mois/l'année actuels

Horodatages de fichiers Linux expliqués avec des exemples

Bash Scripting - Commande Printf expliquée avec des exemples

Suivi du temps avec Timewarrior en ligne de commande

Planification avec cron &At