Команда Date не соответствует спецификациям Linux (Mac OS X Lion) - PullRequest
51 голосов
/ 21 марта 2012

Я уже довольно давно занимаюсь разработкой сценария на своем компьютере с Linux и хотел запустить его и на моем Mac.

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

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

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

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

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

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

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

Ответы [ 3 ]

67 голосов
/ 21 марта 2012

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

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

8 голосов
/ 21 марта 2012

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

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

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

$ python -c 'import time; print(repr(time.time()))'
1 голос
/ 27 февраля 2018

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

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

date [-u] [+format]

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

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

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

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

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

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

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

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

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

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

...