GNU/Linux >> Znalost Linux >  >> Linux

Tisk aktuálního času v milisekundách nebo nanosekundách s vestavěným printf

bash v5 a $EPOCHREALTIME

  • EPOCHREALTIME hodnota s plovoucí desetinnou čárkou s mikrosekundovou zrnitostí

  • EPOCHSECONDS počet sekund od epochy Unix

Správný způsob

Jednoduše:

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

1. O $EPOCHREALTIME

Dávejte pozor:

    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.

Pokud tedy požádám o stejnou proměnnou dvakrát na stejném řádku:

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

nebo jasněji:

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

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

To samé na mém malinovém pi:

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

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

Takže dotazování na tento čas pro vytvoření intergerové části a odděleného procesu zlomkové části by mohlo vést k problémům:(Na stejné lince první přístup k $ EPOCHREALTIME může dát:NNN1.999995 , pak další:NNN2.000002 . Výsledek bude:NNN1.000002 s 1000000 chyba mikrosekund)

2. VAROVÁNÍ! O míchání $EPOCHSECONDS a $EPOCHREALTIME

Použití obou dohromady nejenže vede k první zmíněné chybě!

$EPOCHSECONDS použijte volání na time() který se neaktualizuje neustále, zatímco $EPOCHREALTIME použijte volání gettimeofday() ! Takže výsledky se mohou hodně lišit:

Našel jsem tuto odpověď na time() a gettimeofday() vrací různé sekundy s dobrým vysvětlením.

Pokud to zkusím na svém hostiteli:

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
}

(
Poznámka:Používám read -t místo sleep , protože sleep není vestavěný
Poznámka2:Můžete si pohrát s argumentem funkce, abyste změnili hodnotu časového limitu čtení (spánku)
)

To by mohlo něco vykreslit:

$ 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

Kde celá část z $EPOCHREALTIME se může zvýšit o více než 8 000 mikrosekund před $EPOCHSECONDS (na mém hostiteli).

Poznámka: Zdá se, že to souvisí s nějakou chybou , výsledek se může mezi různými hostiteli nebo na stejném hostiteli po restartu hodně lišit a další věci... Kupodivu jsem je mohl reprodukovat na mnoha různých hostitelích (Intel Core, Intel Xeon, Amd64..), ale ne na raspberry pi! ? (Stejné vydání Debian bash v5.0.3(1), jiná verze jádra.

Správně: To není chyba! Míchání time() a gettimeofday() je chyba!

Vyhněte se tedy použití obou současně !!!

3. O printf "..%06.0f"

Poznámka:Používám %06.0f místo %d abyste zajistili $NSEC být interpretován jako desetinné číslo (s plovoucí desetinnou čárkou), (zabránit osmičkové interpretaci, pokud proměnná začíná 0 ).

Porovnejte:

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

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

a

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

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

Ukázkový běh

Malý test:

počkejte do další sekundy a poté vytiskněte aktuální čas v mikrosekundách

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

Tento test můžete ukončit stisknutím 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. Datum v milisekundách na Openwrt na Arduino Yun?

  2. Použití barev s printf

  3. Příkaz k získání času v milisekundách

  1. 3 tipy pro tisk s Linuxem

  2. Naplánujte si úlohu pomocí příkazu Linux at

  3. Získejte aktuální čas v hodinách a minutách

  1. Spravujte NTP pomocí Chrony

  2. Poprvé s Linuxem:30 instalačních příběhů

  3. Synchronizujte čas serveru Linux se serverem času sítě