Como observado por @Arrow, com date
implementações que suportam %N
como as de GNU ou ast-open, você pode usar %s%3N
para limitar a precisão, mas exceto em ksh93
onde date
pode ser feito para ser a versão embutida do date
do ast-open, o comando date
não está embutido. Levará algumas centenas, senão mil microsegundos, para começar e mais alguns para imprimir a data e retornar.
bash
copiou um subconjunto de ksh93
printf '%(...)T'
format, mas não a %N
part.
Aqui, parece que você precisa usar shells mais avançados, como ksh93
ou zsh
.
Esses shells podem fazer com que sua variável $SECONDS
registre o tempo desde que o shell iniciou (e que você também pode redefinir para qualquer valor) ponto flutuante:
$ typeset -F SECONDS=0; date +%s%3N; echo $SECONDS
1506318780647
0.0017870000
Demorou até 1787 microssegundos para executar o% GNUdate
aqui.
Você pode usar $((SECONDS*1000))
para obter um número de milissegundos, pois ambos os shells suportam aritmética de ponto flutuante (cuidado: ksh93
homenageia a marca decimal do local).
Para o tempo de época como um ponto flutuante, zsh
tem $EPOCHREALTIME
:
$ zmodload zsh/datetime
$ echo $EPOCHREALTIME
1506318947.2758708000
E ksh93
pode usar "$(printf '%(%s.%N)T' now)"
(observe que a substituição de comando de ksh93
não separa processos nem usa pipes para builtins, portanto não é tão cara quanto em outras shells parecidas com Bourne).
Você também pode definir a variável $EPOCHREALTIME
com:
$ EPOCHREALTIME.get() { .sh.value=$(printf "%(%s.%6N)T");
$ echo "$EPOCHREALTIME"
1506333341.962697
Para o registro de data e hora automático, você também pode usar set -o xtrace
e $PS4
que imprime a hora atual. Em zsh
:
$ zsh -c 'PS4="+%D{%s.%.}> "; set -x; sleep 1; date +%s.%N'
+1506332128.753> sleep 1
+1506332129.754> date +%s.%N
1506332129.755322928
Em ksh93:
$ ksh -c 'PS4="+\$(printf "%(%s.%3N)T")> "; set -x; sleep 1; date +%s.%N'
+1506332247.844> sleep 1
+1506332248.851> date +%s.%N
1506332248.853111699
Dependendo do seu caso de uso, você pode contar com moreutils
do ts
para a sua marcação de tempo:
$ (date +%s.%6N; date +%s.%6N) | ts %.s
1506319395.000080 1506319394.970619
1506319395.000141 1506319394.971972
( ts
dá tempo para ler a linha da saída de date
pelo pipe).
Ou para o tempo entre as linhas de saída:
$ (date +%s.%6N; date +%s.%6N) | ts -i %.s
0.000011 1506319496.806554
0.000071 1506319496.807907
Se você deseja ter o tempo necessário para executar um determinado comando (pipeline), também é possível usar a palavra-chave time
, ajustando o formato com $TIMEFORMAT
em bash
:
$ TIMEFORMAT=%E; time date
Mon 25 Sep 09:51:41 BST 2017
0.002
Essas diretivas de formato de hora vêm inicialmente de csh (embora bash
, ao contrário de zsh
ou GNU time
, suporte apenas um subconjunto minúsculo). Em (t) csh, você pode cronometrar cada comando definindo a variável $time
special:
$ csh -xc 'set time = (0 %E); sleep 1; sleep 2'
set time = ( 0 %E )
sleep 1
0:01.00
sleep 2
0:02.00
(o primeiro número ( 0
here) diz que os comandos que levam mais que muitos segundos devem ser cronometrados, o segundo especifica o formato).