it-swarm.com.de

Date-Befehl folgt nicht den Linux-Spezifikationen (Mac OS X Lion)

Ich habe seit einiger Zeit ein Skript für meine Linux-Box entwickelt und wollte es auch auf meinem Mac ausführen.

Ich dachte, dass die Funktionen auf dem Mac mit den Funktionen von Linux identisch sind, aber heute wurde mir klar, dass es falsch war. Ich wusste, dass es weniger Funktionen auf dem Mac gibt, aber ich dachte, dass die Funktionen, die es gab, die gleiche Implementierung hatten.

Dieses Problem bezieht sich speziell auf den Befehl date.

Wenn ich den Befehl auf meinem Linux-Computer mit dem Parameter ausführen, um einige Zeit in Nanosekunden bereitzustellen, erhalte ich das richtige Ergebnis, aber wenn ich ihn auf meinem Mac ausführte, hat er diese Option nicht.

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

Wie kann ich die aktuelle Zeit in Nanosekunden als Bash-Befehl auf dem Mac abrufen?

Im schlimmsten Fall erstelle ich ein kleines Stück Code, das eine Systemfunktion in C oder etwas aufruft, und ruft sie dann in meinem Skript auf.

Jede Hilfe wird sehr geschätzt!

47
Kaushik Shankar

Dies liegt daran, dass OSX und Linux zwei verschiedene Tools verwenden. Linux verwendet die GNU - Version des date-Befehls (daher GNU/Linux). Denken Sie daran, dass Linux Linux und OS X Unix ist. Sie sind anders.

Sie können den Befehl GNU date, der im Paket "coreutils" enthalten ist, von MacPorts installieren. Es wird auf Ihrem System als gdate installiert. Sie können dies entweder verwenden oder die date-Binärdatei mit der neuen gdate-Binärdatei verknüpfen. deine Entscheidung.

64
JoeLinux

man date zeigt an, dass es nicht länger als eine Sekunde dauert. Ich würde empfehlen, eine andere Sprache zu versuchen:

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

Stöhne nicht bei OS X, stöhne bei BSD :-P

8
callumacrae

Es gibt "Linux-Spezifikationen", aber sie regeln das Verhalten des Befehls date nicht wesentlich. Was Sie haben, ist wirklich das Gegenteil - Linux (oder genauer gesagt die GNU User-Space-Tools)) hat eine große Anzahl von Erweiterungen, die nicht kompatibel sind mitUnixnach vernünftiger Definition.

Es gibt eine große Anzahl von Standards, diedodiese Dinge regeln. Die, die Sie betrachten sollten, ist POSIX , das erfordert

date [-u] [+format]

und nichts mehr, was durch das Einhalten von Implementierungen unterstützt werden könnte. (Es gibt andere Standards wie XPG und SUS, die Sie vielleicht auch anschauen möchten, aber zumindest sollten Sie POSIX heutzutage benötigen und erwarten ... endlich.)

Das POSIX-Dokument enthält eine Reihe von Beispielen, aber für dateconversiongibt es nichts. Dies ist jedoch ein praktisches Problem, für das sich viele Skripte an date wenden. Auch für Ihr konkretes Problem gibt es in POSIX nichts, was Sie für die Berichterstellung von Zeiten mit einer Genauigkeit von weniger als einer Sekunde benötigen.

Auf jeden Fall ist es hier nicht wirklich hilfreich, wenn man feststellt, dass * BSD kein Linux ist. Sie müssen nur die Unterschiede verstehen und defensiv codieren. Wenn Ihre Anforderungen komplex oder ungewöhnlich sind, wenden Sie sich möglicherweise an eine Skriptsprache wie Perl oder Python), die diese Art von Datumsformatierungsvorgängen in einer Standardinstallation mehr oder weniger standardmäßig ausführt (obwohl Perl keine nor Python haben eine schnelle und elegante Möglichkeit, ein Date zu erstellenconversionout of the box; Lösungen neigen dazu, etwas gequält zu werden).

In der Praxis können Sie die Manpage MacOS date und Linux one vergleichen und versuchen, Ihre Anforderungen in Einklang zu bringen.

Für Ihre praktischen Anforderungen unterstützt MacOS date keine Formatzeichenfolge mit Nanosekundengenauigkeit. Es ist jedoch auch nicht wahrscheinlich, dass Sie auf dieser Skala nützliche Ergebnisse erhalten, wenn die Ausführung des Befehls eine erhebliche Anzahl von Nanosekunden in Anspruch nimmt. Ich würde mich mit einer Genauigkeit auf Millisekunden-Ebene zufrieden geben (und selbst das wird durch die Ausführungszeit in den letzten Ziffern beeinträchtigt) und multiplizieren, um die Zahl im Nanosekunden-Maßstab zu erhalten.

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

(Beachten Sie die Klammern um das Argument zu print() für Python 3.) Sie werden feststellen, dass PythonGibteinen Wert mit einer Genauigkeit von Nanosekunden an (die letzten Ziffern sind oft keine Nullen), obwohl der Wert zu dem Zeitpunkt, zu dem Sie time.time() ausgeführt haben, offensichtlich nicht mehr korrekt ist.

Um sich ein Bild von der Fehlerrate zu machen,

[email protected]$ 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

Der Overhead vonstartingPython und das Drucken des Werts werden wahrscheinlich ein paar Größenordnungen des Overheads hinzufügen, aber ich habe keine Ahnung Ich habe nicht versucht, das zu quantifizieren. (Die Ausgabe von timeit erfolgt in Sekunden.)

2
tripleee