Come ottenere millisecondi dall'epoca di Unix?


30

Voglio fare uno script bash che misura il tempo di avvio di un browser per quello che sto usando un HTML che ottiene il timestamp sul caricamento in millisecondi usando JavaScript.

Nello script della shell appena prima di chiamare il browser ottengo il timestamp con:

date +%s

Il problema è che ottiene il timestamp in secondi e ne ho bisogno in millisecondi poiché a volte quando viene eseguito una seconda volta il browser si avvia in meno di un secondo e devo essere in grado di misurare quel tempo con precisione usando millisecondi anziché secondi.

Come posso ottenere il timestamp in millisecondi da uno script bash?

Risposte:


28

date +%s.%Nti darà, ad es 1364391019.877418748. % N è il numero di nanosecondi trascorsi nell'attuale secondo. Si noti che è composto da 9 cifre e per impostazione predefinita la data lo riempirà di zeri se è inferiore a 100000000. Questo è in realtà un problema se vogliamo fare matematica con il numero, perché bash tratta i numeri con uno zero iniziale come ottale . Questo riempimento può essere disabilitato utilizzando un trattino nelle specifiche del campo, quindi:

echo $((`date +%s`*1000+`date +%-N`/1000000))

ti darebbe ingenuamente millisecondi dall'epoca.

Tuttavia , come sottolinea Stephane Chazelas nel commento qui sotto, sono due datechiamate diverse che produrranno due volte leggermente diverse. Se il secondo è passato tra loro, il calcolo sarà un intero secondo. Così:

echo $(($(date +'%s * 1000 + %-N / 1000000')))

O ottimizzato (grazie ai commenti qui sotto, anche se questo avrebbe dovuto essere ovvio):

echo $(( $(date '+%s%N') / 1000000));

L'ho provato e funziona, grazie + 1 / accetta!
Eduard Florinescu,

7
Si noti che tra il momento in cui si esegue la prima data e la seconda data, potrebbero essere passati diversi milioni di nanosecondi e potrebbe non essere nemmeno lo stesso secondo. Meglio fare $(($(date +'%s * 1000 + %N / 1000000'))). Non ha ancora molto senso, ma sarebbe più affidabile.
Stéphane Chazelas,

1
Risolto disattivando l'imbottitura zero come indicato in data (1)
Alois Mahdal

3
%Nnon è disponibile in BSD e OS X.
orkoden,

1
Perché non solo echo $(( $(date '+%s%N') / 1000000))?
Hitechcomputergeek il

47

Con la GNU o l'implementazione ast-open di date(o busybox 'se costruito con l' FEATURE_DATE_NANOopzione abilitata), utilizzerei:

$ date +%s%3N

che restituisce millisecondi dall'epoca di Unix.


5
Elegante, simpatico, +1
Eduard Florinescu

1
Voto per l'eleganza
sleepycal

Davvero elegante, +1. Se come me vuoi essere sicuro di %3Nfare il necessario riempimento zero a sinistra (senza leggere i documenti. ;-), puoi fare while sleep 0.05; do date +%s%3N; done, e sì, gli zeri necessari sono lì.
Terry Brown,

Grazie Terry! Tuttavia %3Nè davvero zero imbottito. Inoltre, non credo che la tua soluzione aggiungerebbe zero, ma ritardare la risposta così poco.
javabeangrinder,

javabeangrinder, il codice di @ TerryBrown non era una soluzione , basta testare il codice per verificare che %3Nsia effettivamente 0-padded.
Stéphane Chazelas il

10

Nel caso qualcuno sta usando altre shell oltre bash, ksh93e zshhanno una virgola mobile $SECONDSvariabile se si fa una typeset -F SECONDSche può essere utile per misurare il tempo con una precisione:

$ typeset -F SECONDS=0
$ do-something
something done
$ echo "$SECONDS seconds have elapsed"
18.3994340000 seconds have elapsed

Dalla versione 4.3.13 (2011) zshha una $EPOCHREALTIMEspeciale variabile in virgola mobile nel zsh/datetimemodulo:

$ zmodload zsh/datetime
$ echo $EPOCHREALTIME
1364401642.2725396156
$ printf '%d\n' $((EPOCHREALTIME*1000))
1364401755993

Nota che è derivato dai due numeri interi (per secondi e nanosecondi) restituiti da clock_gettime(). Sulla maggior parte dei sistemi, questa è una precisione maggiore di quella che doublepuò contenere un singolo numero in virgola mobile C , quindi perderai la precisione quando la usi in espressioni aritmetiche (tranne che per le date nei primi mesi del 1970).

$ t=$EPOCHREALTIME
$ echo $t $((t))
1568473231.6078064442 1568473231.6078064

Per calcolare le differenze di tempo ad alta precisione (anche se dubito che avresti bisogno di una precisione superiore ai millisecondi), potresti invece utilizzare l' $epochtimearray speciale (che contiene i secondi e i nanosecondi come due elementi separati).

Dalla versione 5.7 (2018) la strftimeshell incorporata supporta anche un %Nformato di nanosecondi à la GNU datee un %.per specificare la precisione, quindi il numero di millisecondi dall'epoca può essere recuperato anche con:

zmodload zsh/datetime
strftime %s%3. $epochtime

(o memorizzato in una variabile con -s var)


Si noti che la variabile "$ SECONDI" non è connessa / correlata al tempo EPOCH. La parte frazionaria (millisecondi, microsecondi e nanosecondi) può essere abbastanza diversa in ciascuno.
Isacco

8

Per evitare calcoli per ottenere i millisecondi, gli interpreti JavaScript della riga di comando possono aiutare:

bash-4.2$ node -e 'console.log(new Date().getTime())' # node.js
1364391220596

bash-4.2$ js60 -e 'print(new Date().getTime())'       # SpiderMonkey
1364391220610

bash-4.2$ jsc -e 'print(new Date().getTime())'        # WebKit 
1364391220622

bash-4.2$ seed -e 'new Date().getTime()'              # GNOME object bridge
1364391220669

Pacchetti contenenti quegli interpreti su Ubuntu Eoan:


2

In bash 5+ c'è una variabile con microsecondo granularità: $EPOCHREALTIME.

Così:

$ echo "$(( ${EPOCHREALTIME//.} / 1000 ))"
1568385422635

Stampa il tempo dall'epoca (1/1/70) in millisecondi.

In caso contrario, è necessario utilizzare la data. O la data GNU:

echo "$(date +'%s%3N')"

Una delle alternative elencate in https://serverfault.com/a/423642/465827

O brew install coreutilsper OS X

Oppure, se tutto il resto fallisce, compilare (gcc epochInµsec.c) questo programma c (regolare secondo necessità):

#include <stdio.h>
#include <sys/time.h>
int main(void)
{
  struct timeval time_now;
    gettimeofday(&time_now,NULL);
    printf ("%ld secs, %ld usecs\n",time_now.tv_sec,time_now.tv_usec);

    return 0;
}

Si noti che la chiamata a qualsiasi programma esterno richiede tempo per essere letta e caricata dal disco, avviata, eseguita e infine per stampare l'output. Ci vorranno diversi millisecondi. Questa è la precisione minima che potrebbe essere raggiunta con qualsiasi strumento esterno (compresa la data).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.