GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Drucken der aktuellen Zeit in Millisekunden oder Nanosekunden mit eingebautem printf

bash v5 und $EPOCHREALTIME

  • EPOCHREALTIME Fließkommawert mit Mikrosekunden-Granularität

  • EPOCHSECONDS die Anzahl der Sekunden seit der Unix-Epoche

Richtiger Weg

Einfach:

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

1. Über $EPOCHREALTIME

Bitte beachten:

    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.

Wenn ich also zweimal in derselben Zeile nach derselben Variablen frage:

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

oder deutlicher:

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

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

Dasselbe auf meinem Himbeer-Pi:

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

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

Daher kann es zu Problemen führen, wenn Sie diese zwei Mal zum Erstellen des ganzzahligen Teils und des Bruchteils abfragen, was zu Problemen führen kann:(In derselben Zeile erster Zugriff auf $ EPOCHREALTIME könnte geben:NNN1.999995 , dann weiter:NNN2.000002 . Als Ergebnis wird:NNN1.000002 mit 1000000 Mikrosekundenfehler)

2. WARNUNG! Über das Mischen von $EPOCHSECONDS und $EPOCHREALTIME

Die Verwendung beider zusammen führte nicht nur zum erstgenannten Fehler!

$EPOCHSECONDS Rufen Sie time() an die nicht ständig aktualisiert wird, während $EPOCHREALTIME Verwenden Sie den Aufruf von gettimeofday() ! Die Ergebnisse können also sehr unterschiedlich sein:

Ich habe diese Antwort auf time() und gettimeofday() gefunden, die unterschiedliche Sekunden zurückgeben mit guter Erklärung.

Wenn ich es auf meinem Host versuche:

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
}

(
Hinweis:Ich verwende read -t statt sleep , weil sleep ist nicht eingebaut
Nota2:Sie könnten mit dem Argument der Funktion spielen, um den Wert des Lese-Timeouts (sleep) zu ändern.
)

Dies könnte etwas wie folgt darstellen:

$ 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

Wobei ganzzahliger Teil von $EPOCHREALTIME um mehr als 8000 erhöhen könnte Mikrosekunden vor $EPOCHSECONDS (auf meinem Host).

Hinweis: Dies scheint mit einem Fehler zusammenzuhängen , das Ergebnis kann sich nach dem Neustart zwischen verschiedenen Hosts oder auf demselben Host stark unterscheiden, und andere Dinge ... Seltsamerweise konnte ich sie auf vielen verschiedenen Hosts (Intel Core, Intel Xeon, Amd64 ...) reproduzieren, aber nicht auf Himbeer-Pi! ? (Gleiches Debian bash v5.0.3(1)-Release), andere Kernel-Version.

Richtig: Das ist kein Fehler! Mischen von time() und gettimeofday() ist ein Fehler!

Vermeiden Sie es also, beides zusammen zu verwenden !!!

3. Über printf "..%06.0f"

Hinweis:Ich verwende %06.0f statt %d um $NSEC sicherzustellen als Dezimalzahl (float) zu interpretieren, (oktale Interpretation verhindern, wenn Variable mit 0 beginnt ).

Vergleichen Sie:

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

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

und

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

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

Probelauf

Kleiner Test:

bis zur nächsten Sekunde warten, dann aktuelle Zeit mit Mikrosekunden drucken

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

Sie können diesen Test beenden, indem Sie Return drücken

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. Synchronisieren Sie die Linux-Serverzeit mit dem Netzwerkzeitserver

  2. Datum in Millisekunden auf Openwrt auf Arduino Yun?

  3. Prozessstartzeit mit Zeitzone?

  4. Befehl zum Abrufen der Zeit in Millisekunden

  5. So erstellen Sie unter Linux eine Datei mit einem Namen, der das aktuelle Datum und die aktuelle Uhrzeit enthält

So erhalten Sie das aktuelle Datum und die Uhrzeit in JavaScript

Erstellen Sie Verzeichnisse oder Dateien, die nach aktuellem Datum / Uhrzeit / Monat / Jahr benannt sind

Linux-Dateizeitstempel mit Beispielen erklärt

Bash-Scripting – Printf-Befehl mit Beispielen erklärt

Zeiterfassung mit Timewarrior auf der Kommandozeile

Terminplanung mit cron &At