Команда Date не соответствует спецификациям Linux (Mac OS X Lion)

Я занимаюсь разработкой script в моем linux box в течение некоторого времени и хотел запустить его и на моем Mac.

Я думал, что функции на Mac такие же, как и функции на linux, но сегодня я понял, что это неправильно. Я знал, что на Mac существует меньше функций, но я думал, что функции, которые существовали, имели ту же реализацию.

Эта проблема специально относится к команде date.

Когда я запускаю команду на моей машине linux с параметром, чтобы предоставить некоторое время в наносекундах, я получаю правильный результат, но когда я запускаю его на своем mac, у него нет этой опции.

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

Как мне получить текущее время в наносекундах как команду bash на Mac?

В худшем случае я создаю небольшой фрагмент кода, который вызывает системную функцию на C или что-то еще, а затем вызывает его в моем script.

Любая помощь очень ценится!

Ответ 1

Это потому, что OSX и Linux используют два разных набора инструментов. Linux использует версию команды date GNU (следовательно, GNU/Linux). Помните, что Linux - это Linux, а OS X - это Unix. Они разные.

Вы можете установить команду date GNU, которая входит в пакет "coreutils" от MacPorts. Он будет установлен в вашей системе как gdate. Вы можете использовать это или связать двоичный файл date с новым двоичным gdate; твой выбор.

Ответ 2

man date указывает на то, что она не превышает одной секунды. Я бы порекомендовал попробовать другой язык (Python 2):

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

Для Python 3 используйте:

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

Ответ 3

Существуют "спецификации Linux", но они мало регулируют поведение команды date. То, что у вас есть, на самом деле противоположное - Linux (или, точнее, инструменты пользовательского пространства GNU) имеет большое количество расширений, которые не совместимы с Unix по какому-либо разумному определению.

Существует большое количество стандартов, которые регулируют эти вещи. То, на что вы должны обратить внимание, это POSIX, который требует

date [-u] [+format]

и больше ничего не должно быть поддержано придерживающимися реализациями. (Существуют и другие стандарты, такие как XPG и SUS, на которые вы, возможно, захотите взглянуть, но, по крайней мере, вам следует ожидать и ожидать POSIX в эти дни... наконец.)

Документ POSIX содержит ряд примеров, но нет ничего для преобразования даты, что, однако, является практической проблемой, к которой многие сценарии обращаются на date. Кроме того, для вашей конкретной проблемы в POSIX нет ничего, что сообщало бы о времени с точностью до секунды.

В любом случае, понять, что * BSD - это не Linux, здесь не очень-то полезно; Вы просто должны понять, в чем различия, и защищать код. Если ваши требования сложны или необычны, возможно, обратитесь к языку сценариев, например Perl или Python, который выполняет стандартные операции форматирования даты более или менее стандартно при стандартной установке (хотя ни в Perl, ни в Python нет быстрого и элегантного способа сделать преобразование даты из коробки, либо, решения, как правило, несколько замучены).

В практическом плане вы можете сравнить справочную страницу date MacOS и Linux и попытаться согласовать ваши требования.

Для вашего практического требования MacOS date не поддерживает строки формата с точностью до наносекунды, но вы также вряд ли получите полезные результаты в таком масштабе, когда выполнение команды займет значительное количество наносекунд. Я согласился бы с точностью до миллисекундного уровня (и даже это будет отброшено временем выполнения в последних цифрах) и умножил бы, чтобы получить число в масштабе наносекунды.

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

(Обратите внимание на круглые скобки вокруг аргумента print() для Python 3.) Вы заметите, что Python действительно сообщает значение с точностью до наносекунды (последние цифры часто не time.time()), хотя к тому времени, как вы запустили time.time() значение, очевидно, больше не будет правильным.

Чтобы получить представление о частоте появления ошибок,

[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

Затраты на запуск Python и печать значения, вероятно, добавят несколько порядков издержек, реально, но я не пытался это количественно оценить. (Вывод timeit - в секундах.)