La commande de date ne suit pas les spécifications Linux (Mac OS X Lion)

Je développe un script sur mon linux depuis un certain temps déjà et je voulais aussi le lancer sur mon Mac.

Je pensais que les fonctions sur le Mac étaient les mêmes que les fonctions sur Linux, mais aujourd’hui j’ai réalisé que c’était faux. Je savais que moins de fonctions existaient sur le Mac, mais je pensais que les fonctions qui existaient avaient la même implémentation.

Ce problème concerne spécifiquement la commande de date .

Lorsque j’exécute la commande sur ma machine Linux avec le paramètre pour fournir du temps en nanosecondes, j’obtiens le résultat correct, mais lorsque je l’exécute sur mon mac, il n’a pas cette option.

 Linux-Machine> date +%N 55555555555 #Current time in nanoseconds Mac-Machine> date +%N N 

Comment puis-je obtenir l’heure actuelle en nanosecondes sous la forme d’une commande bash sur le Mac?

Le pire des cas est que je crée un petit morceau de code qui appelle une fonction système en C ou quelque chose, puis l’appelle dans mon script.

Toute aide est très appréciée!

Cela est dû au fait qu’OSX et Linux utilisent deux ensembles d’outils différents. Linux utilise la version GNU de la commande de date (donc GNU / Linux). Rappelez-vous que Linux est Linux et OS X est Unix. Ils sont différents

Vous pouvez installer la commande GNU date qui est incluse dans le package “coreutils” de MacPorts . Il sera installé sur votre système en tant que gdate . Vous pouvez soit l’utiliser, soit lier le binary de date au nouveau binary gdate ; votre choix.

man date indique que cela ne dépasse pas une seconde. Je recommanderais d’essayer une autre langue:

 $ python -c'import time; print repr(time.time())' 1332334298.898616 

Ne vous plaignez pas à OS X, gémissez à BSD 😛

Il existe des “spécifications Linux” mais elles ne régulent pas beaucoup le comportement de la commande de date . Ce que vous avez est vraiment le contraire – Linux (ou plus précisément les outils d’espace utilisateur GNU) a un grand nombre d’extensions qui ne sont pas compatibles avec Unix par une définition raisonnable.

Il existe un grand nombre de normes qui réglementent ces choses. Celui que vous devriez regarder est POSIX qui nécessite

 date [-u] [+format] 

et rien de plus à supporter par des implémentations adhérentes. (Il y a d’autres standards comme XPG et SUS que vous voudrez peut-être examiner également, mais à tout le moins, vous devriez demander et attendre POSIX ces derniers temps … enfin.)

Le document POSIX contient un certain nombre d’exemples, mais il n’ya rien pour la conversion de date, mais c’est un problème pratique auquel beaucoup de scripts sont confrontés. De plus, pour votre problème concret, il n’ya rien pour les temps de rapport avec une précision inférieure à la seconde dans POSIX.

Quoi qu’il en soit, le fait que BSD n’est pas Linux n’est pas vraiment utile ici; il suffit de comprendre quelles sont les différences et de coder défensivement. Si vos exigences sont complexes ou inhabituelles, optez peut-être pour un langage de script tel que Perl ou Python, qui exécute plus ou moins ces opérations de formatage de date dans une installation standard (bien que ni Perl ni Python ne disposent d’une méthode rapide et élégante). faire la conversion de date hors de la boîte, soit, les solutions ont tendance à être un peu torturé).

En termes pratiques, vous pouvez comparer la page de manuel de date MacOS et celle de Linux et essayer de concilier vos besoins.

Pour votre besoin pratique, la date MacOS ne prend en charge aucune chaîne de format avec une précision à la nanoseconde, mais vous ne recevrez probablement pas de résultats utiles à cette échelle lorsque l’exécution de la commande prendra un nombre important de nanosecondes. Je me contenterais de la précision au niveau de la milliseconde (et même de la durée d’exécution dans les derniers chiffres) et je multiplierais pour obtenir le nombre à l’échelle nanoseconde.

 nanoseconds () { python -c 'import time; print(int(time.time()*1000*1000*1000))' } 

(Notez les parenthèses autour de l’argument de print() pour Python 3.) Vous remarquerez que Python rapporte une valeur avec une précision à la nanoseconde (les derniers chiffres ne sont souvent pas des zéros), bien time.time() moment où vous time.time() la valeur ne sera évidemment plus correcte.

Pour avoir une idée du taux d’erreur,

 bash@macos-high-sierra$ python3 Python 3.5.1 (default, Dec 26 2015, 18:08:53) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import time >>> import timeit >>> def nanoseconds (): ... return int(time.time()*1000*1000*1000) ... >>> timeit.timeit(nanoseconds, number=10000) 0.0066173350023746025 >>> timeit.timeit('int(time.time()*1000*1000*1000)', number=10000) 0.00557799199668807 

La surcharge de démarrage de Python et l’impression de la valeur vont probablement append quelques ordres de grandeur de surcharge, de manière réaliste, mais je n’ai pas tenté de quantifier cela. (La sortie de timeit est en secondes.)