web-dev-qa-db-ja.com

日付コマンドが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

Macでbashコマンドとして現在の時間をナノ秒単位で取得するにはどうすればよいですか?

最悪の場合は、Cなどのシステム関数を呼び出す小さなコードを作成してから、スクリプト内で呼び出します。

どんな助けも大歓迎です!

54
Kaushik Shankar

これは、OSXとLinuxが2つの異なるツールセットを使用しているためです。 LinuxはGNUバージョンのdateコマンドのバージョン(したがって、GNU/Linux)を使用します。LinuxはLinuxであり、OS XはUnixであることに注意してください。

MacPorts から「coreutils」パッケージに含まれるGNU dateコマンドをインストールできます。 system as gdate。これを使用するか、dateバイナリを新しいgdateバイナリにリンクすることができます。

69
JoeLinux

man dateは、1秒を超えないことを示します。別の言語(Python 2)を試すことをお勧めします。

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

Python 3の場合:

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

「Linux仕様」はありますが、dateコマンドの動作をあまり規制していません。あなたが持っているものは本当に反対です-Linux(より具体的にはGNUユーザースペースツール)には、と互換性のない多くの拡張機能がありますUnix合理的な定義による。

これらのことを規制するdo規格が多数あります。見るべきものは [〜#〜] posix [〜#〜] です。

_date [-u] [+format]
_

そして、それを実装することによってサポートされるものは何もありません。 (XPGやSUSのような他の規格もありますが、これらも見たいかもしれませんが、少なくとも、最近ではPOSIXを要求し、期待する必要があります...最後に。)

POSIXドキュメントには多くの例が含まれていますが、日付conversionには何もありませんが、これは多くのスクリプトがdateに変える実用的な問題ですにとって。また、具体的な問題については、POSIXでは1秒未満の精度で時間を報告することはできません。

とにかく、* BSDがLinuxではないことを理解することは、ここではあまり役に立ちません。違いが何であるかを理解し、防御的にコーディングする必要があります。要件が複雑または異常な場合は、PerlまたはPythonのようなスクリプト言語を使用して、標準インストールで多かれ少なかれこれらのタイプの日付フォーマット操作を実行します(ただし、Perl nor Python日付を素早く簡単に行う方法がありますconversionどちらでも、解決策はやや拷問された)。

実際には、 MacOS date manページLinux one を比較して、要件の調整を試みることができます。

実際の要件として、MacOS dateはナノ秒精度のフォーマット文字列をサポートしていませんが、コマンドの実行にかなりの数のナノ秒がかかる場合、そのスケールで有用な結果を受け取る可能性は低いです。私は、ミリ秒レベルの精度に落ち着き(さらに、最後の桁の実行時間までにスローオフされます)、乗算してナノ秒スケールの数値を取得します。

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

(Python 3.の場合、print()への引数を囲む括弧に注意してください。)Pythondoesナノ秒の精度で値を報告します(最後の桁は多くの場合ゼロではありません)。ただし、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
_

startingPythonおよび値を印刷すると、おそらく数桁のオーバーヘッドが現実的に追加されます、しかし、私はそれを定量化しようとしませんでした(timeitからの出力は秒単位です)。

2
tripleee