web-dev-qa-db-fra.com

Comment puis-je obtenir l'heure Unix actuelle en millisecondes dans Bash?

Comment puis-je obtenir l'heure Unix actuelle en millisecondes (c'est-à-dire le nombre de millisecondes depuis l'époque Unix le 1er janvier 1970)?

253
Richard

Cette:

date +%s 

renverra le nombre de secondes depuis l'époque.

Cette:

date +%s%N

renvoie les secondes et les nanosecondes actuelles.

Donc:

date +%s%N | cut -b1-13

vous donnera le nombre de millisecondes depuis l'époque - secondes actuelles plus les trois gauche des nanosecondes.


et de MikeyB - echo $(($(date +%s%N)/1000000)) (la division par 1000 n'apporte qu'en microsecondes)

283
warren

Vous pouvez simplement utiliser %3N pour tronquer les nanosecondes aux 3 chiffres les plus significatifs (qui sont alors des millisecondes):

$ date +%s%3N
1397392146866

Cela fonctionne par exemple sur mon Kubunt 12.04 (Pangolin précis).

Mais sachez que %N peut ne pas être implémenté en fonction de votre système cible. Par exemple. testé sur un système embarqué (buildroot rootfs, compilé en utilisant un non-HF ARM cross toolchain) il n'y avait pas de %N:

$ date +%s%3N
1397392146%3N

(Et aussi ma (non enracinée) Android n'a pas %N.)

111
Joe

date +%N Ne fonctionne pas sur OS X, mais vous pouvez utiliser l'un des

  • Ruby : Ruby -e 'puts Time.now.to_f'
  • Python : python -c 'import time; print time.time()'
  • Node.js : node -e 'console.log(Date.now())'
  • PHP : php -r 'echo microtime(TRUE);'
  • Elixir : DateTime.utc_now() |> DateTime.to_unix(:millisecond)
  • Internet: wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
  • ou pour les millisecondes arrondies à la seconde la plus proche date +%s000
67
Lri

Ma solution n'est pas la meilleure, mais elle a fonctionné pour moi:

date +%s000

J'avais juste besoin de convertir une date comme 2012-05-05 en millisecondes.

11
Pablo

Il suffit de jeter cela, mais je pense que la bonne formule avec la division serait:

echo $(($(date +%s%N)/1000000))
10
WillB

Pour les personnes qui suggèrent d'exécuter des programmes externes pour millisecondes ... à ce rythme, vous pourriez aussi bien faire ceci:

wget -qO- http://www.timeapi.org/utc/now?\\s.\\N

Le point étant: avant de choisir une réponse à partir d'ici, veuillez garder à l'esprit que tous les programmes ne s'exécuteront pas en une seconde. Mesure!

7
Camilo Martin

Cette solution fonctionne sur macOS.

Si vous envisagez d'utiliser un script Bash et que vous disposez de Python disponible, vous pouvez utiliser ce code:

#!/bin/bash

python -c 'from time import time; print int(round(time() * 1000))'
7
Frank Thonig

Si vous cherchez un moyen d'afficher la durée d'exécution de votre script, les éléments suivants fourniront un résultat (pas complètement précis):

Au plus près du début de votre script, saisissez ce qui suit

basetime=$(date +%s%N)

Cela vous donnera une valeur de départ de quelque chose comme 1361802943996000000.

À la fin de votre script, utilisez ce qui suit

echo "runtime: $(echo "scale=3;($(date +%s%N) - ${basetime})/(1*10^09)" | bc) seconds"

qui affichera quelque chose comme

runtime: 12.383 seconds

Remarques:

(1 * 10 ^ 09) peut être remplacé par 1000000000 si vous le souhaitez

"scale=3" est un paramètre assez rare qui contraint bc à faire ce que vous voulez. Il y en a beaucoup plus!

Je n'ai testé cela que sur Windows 7/MinGW ... Je n'ai pas de boîte * nix à portée de main.

3
user161733

Voici comment obtenir du temps en millisecondes sans effectuer de division. C'est peut-être plus rapide ...

# test=`date +%s%N`
# testnum=${#test}
# echo ${test:0:$testnum-6}
1297327781715

Mise à jour: Une autre alternative dans Bash pur qui ne fonctionne qu'avec Bash 4.2+ est la même que ci-dessus, mais utilisez printf pour obtenir la date. Ce sera certainement plus rapide, car aucun processus n'est dérivé du processus principal.

printf -v test '%(%s%N)T' -1
testnum=${#test}
echo ${test:0:$testnum-6}

Un autre inconvénient ici est que votre implémentation strftime devrait prendre en charge %s et %N ce qui est pas le cas sur ma machine de test. Voir man strftime pour les options prises en charge. Regarde aussi man bash pour voir la syntaxe printf. -1 et -2 sont des valeurs spéciales pour le temps.

2
akostadinov

N'ajoutant rien de révolutionnaire ici par rapport à la réponse acceptée, mais simplement pour la rendre facilement réutilisable pour ceux d'entre vous qui sont plus récents à Bash. Notez que cet exemple fonctionne sous OS X et sur les anciens Bash, ce qui était une exigence pour moi personnellement.

nowInMs() {
  echo "$(($(date +'%s * 1000 + %-N / 1000000')))"
}

Vous pouvez maintenant exécuter

TIMESTAMP="$(nowInMs)";

L'horodatage le plus précis que nous pouvons obtenir (au moins pour Mac OS X) est probablement le suivant:

python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'

1490665305.021699

Mais nous devons garder à l'esprit qu'il faut environ 30 millisecondes pour fonctionner. Nous pouvons le couper à l'échelle d'une fraction de 2 chiffres, et au tout début calculer le frais généraux moyens de lecture de l'heure, puis l'enlever de la mesure. Voici un exemple:

function getTimestamp {
  echo `python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")' | cut -b1-13` 
}
function getDiff {
  echo "$2-$1-$MeasuringCost" | bc
}
prev_a=`getTimestamp`
acc=0
ITERATIONS=30
for i in `seq 1 $ITERATIONS`;do 
  #echo -n $i 
  a=`getTimestamp`
  #echo -n "   $a"
  b=`echo "$a-$prev_a" | bc`
  prev_a=$a
  #echo "  diff=$b"
  acc=`echo "$acc+$b" | bc`
done
MeasuringCost=`echo "scale=2; $acc/$ITERATIONS" | bc`
echo "average: $MeasuringCost sec"
t1=`getTimestamp`
sleep 2
t2=`getTimestamp`
echo "measured seconds: `getDiff $t1 $t2`"

Vous pouvez décommenter les commandes echo pour mieux voir comment cela fonctionne.

Les résultats de ce script sont généralement l'un de ces 3 résultats:

measured seconds: 1.99
measured seconds: 2.00
measured seconds: 2.01
2
ishahak

Utiliser date et expr peut vous y conduire, c'est-à-dire.

X=$(expr \`date +%H\` \\* 3600 + \`date +%M\` \\* 60 + \`date +%S\`)
echo $X

Développez-le pour faire ce que vous voulez

Je me rends compte que cela ne donne pas de millisecondes depuis Epoch, mais cela pourrait toujours être utile comme réponse pour certains cas, tout dépend de ce dont vous avez vraiment besoin, multipliez par 1000 si vous avez besoin d'un nombre de millisecondes: D

Le moyen le plus simple serait de créer un petit exécutable (à partir de C f.ex.) et de le mettre à disposition du script.

1
Johan Andersson

En regroupant les réponses précédentes, sous OS X,

ProductName:    Mac OS X
ProductVersion:    10.11.6
BuildVersion:    15G31+

tu peux faire comme

microtime() {
    python -c 'import time; print time.time()'
}
compute() {
    local START=$(microtime)
    #$1 is command $2 are args
    local END=$(microtime)
    DIFF=$(echo "$END - $START" | bc)
    echo "$1\t$2\t$DIFF"
}
1
loretoparisi

(répéter des réponses précédentes) date +%N ne fonctionne pas sur OS X, mais vous pouvez également utiliser:

Perl (nécessite le module Time :: Format). Ce n'est peut-être pas le meilleur module CPAN à utiliser, mais il fait le travail. Time :: Format est généralement disponible avec les distributions.

Perl -w -e'use Time::Format; printf STDOUT ("%s.%s\n", time, $time{"mmm"})'
1
TVNshack

Si vous voulez un calcul de Shell simple, c'est simple et portable, en utilisant réponse de Frank Thonig :

now() {
    python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'
}
seismo:~$ x=`now`
seismo:~$ y=`now`
seismo:~$ echo "$y - $x" | bc
5.212514
0
Bill Cheswick

Pour Alpine Linux (de nombreuses images Docker) et éventuellement d'autres environnements Linux minimaux, vous pouvez abuser de adjtimex:

adjtimex | awk '/(time.tv_usec):/ { printf("%06d\n", $2) }' | head -c3

adjtimex est utilisé pour lire (et définir) les variables temporelles du noyau. Avec awk vous pouvez obtenir les microsecondes, et avec head vous pouvez utiliser uniquement les 3 premiers chiffres.

Je n'ai aucune idée de la fiabilité de cette commande.

Remarque: Volé sans vergogne à cette réponse

0
Qw3ry