シェルスクリプトで何かの処理を実行する際に、その実行にかかった時間を秒単位で計測したい場合は次のように実行することができます。
dt_start=$( date +"%s" ) 何かの処理 dt_end=$( date +"%s" ) elapsed=$((dt_end - dt_start)) echo ${elapsed}
それでは、今度はミリ秒単位で計測しようと思って次のように実行してみると、Linux では問題なく計測できますが、macOS では意図通りに動作しません。
dt_start=$( date +"%s%3N" ) 何かの処理 dt_end=$( date +"%s%3N" ) elapsed=$(( dt_end - dt_start )) echo ${elapsed}
この理由は、macOS の date コマンドでは "%N" をサポートしていないためです。Linux では次のように結果を返しますが、
$ date +"%s%3N" 1613896343808
同じことを macOS で実行すると、こうなってしまいます。
$ date +"%s%3N" 1613896453N
このため、別の方法での解決策を考えてみたのですが、perl の Times::Hires を用いればミリ秒単位の時刻を取得できることに気づきました。具体的には次のように実行します。
$ perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)' 1613896697373
したがって、macOS のときだけ上記のように実行したいと考えた場合は、uname の値が Darwin の場合だけ perl を用いるように実装すれば良いでしょう。ただし RHEL, CentOS, Ubuntu でも perl はインストール済みのことが多いと思いますので、環境によらず、この方法でミリ秒単位の時刻を取得できると考えて良いでしょう。
今回の例を上記の方法で書き直すと、次のようになります。
dt_start=$( perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)' ) 何かの処理 dt_end=$( perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)' ) elapsed=$((dt_end - dt_start)) echo ${elapsed}