it-roy-ru.com

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

Я уже довольно давно разрабатываю скрипт на своем 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 или что-то в этом роде, а затем вызываю ее в своем скрипте.

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

47
Kaushik Shankar

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

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

64
JoeLinux

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

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

Не стонать на OS X, стонать на BSD :-P

8
callumacrae

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

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

date [-u] [+format]

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

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

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

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

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

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

(Обратите внимание на круглые скобки вокруг аргумента print() для Python 3.) Вы заметите, что Python делает сообщает значение с точностью до наносекунды (последние цифры часто не равны нулю), хотя к тому времени, как вы запустили 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 в секундах.)

1
tripleee