GNU/Linux >> Linux Esercitazione >  >> Linux

Stampa dell'ora corrente in millisecondi o nanosecondi con printf incorporato

bash v5 e $EPOCHREALTIME

  • EPOCHREALTIME valore in virgola mobile con granularità di microsecondi

  • EPOCHSECONDS il numero di secondi dall'epoca Unix

Modo corretto

Semplicemente:

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

1. Circa $EPOCHREALTIME

Si prega di prestare attenzione:

    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.

Quindi, se chiedo la stessa variabile due volte nella stessa riga:

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

o più chiaramente:

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

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

Lo stesso sul mio raspberry-pi:

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

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

Quindi chiedere questa due volte per costruire la parte intera e la parte frazionaria è un processo separato potrebbe portare a problemi:(Sulla stessa riga primo accesso a $ EPOCHREALTIME potrebbe dare:NNN1.999995 , quindi successivo:NNN2.000002 . Il risultato diventerà:NNN1.000002 con 1000000 errore di microsecondi)

2. AVVERTIMENTO! A proposito di mescolare $EPOCHSECONDS e $EPOCHREALTIME

L'uso di entrambi insieme non solo porta al bug menzionato per primo!

$EPOCHSECONDS usa la chiamata a time() che non viene aggiornato costantemente, mentre $EPOCHREALTIME usa la chiamata a gettimeofday() ! Quindi i risultati potrebbero differire molto:

Ho trovato Questa risposta a time() e gettimeofday() restituiscono secondi diversi con una buona spiegazione.

Se provo sul mio host:

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:io uso read -t invece di sleep , perché sleep non è integrato
Nota2:potresti giocare con l'argomento della funzione per cambiare il valore del timeout di lettura (sleep)
)

Questo potrebbe rendere qualcosa di piccolo:

$ 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

Dove parte intera di $EPOCHREALTIME potrebbe aumentare di oltre 8000 microsecondi prima di $EPOCHSECONDS (sul mio host).

Nota: Questo sembra essere collegato a qualche bug , il risultato potrebbe differire molto tra host diversi o sullo stesso host dopo il riavvio e altre cose ... Stranamente potrei riprodurli su molti host diversi (Intel Core, Intel Xeon, Amd64 ..) ma non su Raspberry Pi! ? (Stesso rilascio di Debian bash v5.0.3(1)), diversa versione del kernel.

Corretto: Questo non è un bug! Mescolando time() e gettimeofday() è un bug!

Quindi evita di usarli entrambi insieme!!!

3. Informazioni su printf "..%06.0f"

Nota:utilizzo %06.0f invece di %d per garantire $NSEC da interpretare come decimale (virgola mobile), (impedisci l'interpretazione ottale se la variabile inizia con 0 ).

Confronta:

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

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

e

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

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

Esecuzione di esempio

Piccolo test:

attendere fino al secondo successivo, quindi stampare l'ora corrente con i microsecondi

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

Puoi terminare questo test premendo Invio

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. Sincronizza l'ora del server Linux con il server dell'ora di rete

  2. Usare i colori con printf

  3. Comando per ottenere il tempo in millisecondi

  4. Ottieni l'ora corrente in ore e minuti

  5. In Linux come creare un file con un nome che sia la data e l'ora correnti

Come ottenere la data e l'ora correnti in JavaScript

Crea directory o file denominati con data/ora/mese/anno correnti

Timestamp dei file Linux spiegati con esempi

Scripting Bash – Spiegazione del comando Printf con esempi

Tracciare il tempo con Timewarrior alla riga di comando

Programmazione con cron &At