Macos Date命令不符合Linux规范(Mac OS X Lion)

Macos Date命令不符合Linux规范(Mac OS X Lion),macos,bash,date,scripting,porting,Macos,Bash,Date,Scripting,Porting,我已经在我的linux机器上开发了一段时间了,我也想在我的Mac上运行它 我原以为Mac上的函数与linux上的函数相同,但今天我意识到这是错误的。我知道Mac上存在的函数较少,但我认为确实存在的函数具有相同的实现 此问题与date命令有关 当我在linux机器上运行该命令时,使用参数以纳秒为单位提供一些时间,我会得到正确的结果,但当我在mac上运行该命令时,它没有该选项 Linux-Machine> date +%N 55555555555 #Current time in nanose

我已经在我的linux机器上开发了一段时间了,我也想在我的Mac上运行它

我原以为Mac上的函数与linux上的函数相同,但今天我意识到这是错误的。我知道Mac上存在的函数较少,但我认为确实存在的函数具有相同的实现

此问题与
date
命令有关

当我在linux机器上运行该命令时,使用参数以纳秒为单位提供一些时间,我会得到正确的结果,但当我在mac上运行该命令时,它没有该选项

Linux-Machine> date +%N
55555555555 #Current time in nanoseconds
Mac-Machine> date +%N
N
如何在Mac上获取当前时间(以纳秒为单位)作为bash命令

最糟糕的情况是,我创建了一小段代码,用C或其他语言调用系统函数,然后在脚本中调用它


非常感谢您的帮助

人工日期
表示它不会超过1秒。我建议尝试另一种语言(Python 2):

对于Python 3,请使用:

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

这是因为OSX和Linux使用两套不同的工具。Linux使用GNU版本的
date
命令(因此是GNU/Linux)。请记住,Linux是Linux,OSX是Unix。他们是不同的

您可以从安装GNU
date
命令,该命令包含在“coreutils”包中。它将作为
gdate
安装在您的系统上。您可以使用它,或者将
date
二进制文件与新的
gdate
二进制文件链接;您的选择。

有“Linux规范”,但它们对
date
命令的行为没有太多的规范。事实恰恰相反——Linux(或者更具体地说是GNU用户空间工具)有大量扩展,根据任何合理的定义,这些扩展都与Unix不兼容

有大量的标准来规范这些事情。你应该看到的是

date [-u] [+format]
而且没有更多的东西需要通过坚持实现来支持。(还有其他一些标准,比如XPG和SUS,您可能也想看看,但至少,您现在应该需要并期待POSIX……最后)

POSIX文档包含许多示例,但是没有关于日期转换的任何内容,这是一个实际问题,许多脚本都会使用
date
。另外,对于您的具体问题,POSIX中报告时间的精度不到秒

无论如何,抱怨BSD不是Linux在这里并没有什么帮助;你只需要理解它们之间的区别,并进行防御性编码。如果您的需求很复杂或不寻常,那么可以求助于像Perl或Python这样的脚本语言,它们在标准安装中或多或少地执行这些类型的日期格式化操作(尽管Perl和Python都没有一种快速而优雅的方式来进行开箱即用的日期转换;解决方案往往有点麻烦)

实际上,您可以比较和,并尝试协调您的需求

根据您的实际需求,MacOS
date
不支持任何纳秒级精度的格式字符串,但当执行命令需要大量纳秒级时,您也不可能在该范围内收到有用的结果。我同意毫秒级精度(即使是最后一个数字中的执行时间也会使其消失)然后乘以以纳秒为单位的数字

nanoseconds () {
      python -c 'import time; print(int(time.time()*1000*1000*1000))'
}
(注意Python 3的
print()
参数周围的括号。)您会注意到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
的输出以秒为单位。)

最糟糕的是sed;-)在遵守某些Unix标准方面,我不会依赖Linux。Mac OS X遵循的是单一的Unix规范V3,而不是Linux。此外,从bash命令获得的纳秒精度的日期非常精确,但没有那么精确。您需要什么?感谢您的输入。我将了解GNU与BSD的区别,并查看ces在sed之间。@mouviciel,我想创建一个自定义的
time
命令。FWIW,zsh with
zmodload zsh/datetime
将变量
$EPOCHREALTIME
作为浮点历元时间戳提供给您。当然,如果不使用zsh,它对您没有多大帮助,但一般来说,通过分叉过程来获得精确的时间值e(通过使用
日期
)是有问题的。是的,通过“保证”一个唯一的时间戳(与只获取纪元秒相比)它可能稍微优越一些,但这就是问题所在。当我需要知道它现在是多少纳秒时,我总是启动Python解释器。-)哈哈,说得好-但你能想出更好的解决方案吗?谢谢你的回答@Callum Macrae,但我想我不得不选择另一个答案,因为它会给我更准确的结果。这很公平。我不知道你没有分发脚本,如果是这样的话,你就不能使用gdate了;e、 g.GNU的强大的
--date=
选项
date
。值得注意的是,coreutils也在其中,这使得安装变得很简单。只需安装自制软件,然后
brew安装coreutils
,您就有了gdate。我知道这已经有2年多的历史了,但谢谢!我有一个非常复杂的日期格式片段,在一个大规模应用程序中使用的脚本中
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