それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

date コマンドと bash でタイマー(カウントアップ)を作る

date を使うと整数値の秒が取れる

date +%s

整数値で秒が取れるなら、タイマーも作れそうですよね。

整数の四則演算 と 組み合わせる。

echo $(( $now - $start))

これで、現在の時刻が取れる。

改行(CRLF)が邪魔なので

CRLFをしてしまうと1行次に行ってしまうのでCRだけをしてLineFeedをしないようにしてカレントの行を上書きする

時刻をフォーマットする

date コマンドで時刻をフォーマットする

date +%H:%M:%S @$time

引数に @1345 と整数時間を入れることで UNIX Epoch 1980-01-01 :00:00:00 からの経過時間として解釈してくれる。

これを利用して時間をHH:MM:SS にフォーマットをできる。

全てを組み合わせる

  • date で 整数秒
  • printf で 先頭へ
  • date @ で時間をフォーマット

これらを組み合わせて sleep すると、タイマーができるやったね

タイマーサンプル

#!/bin/bash

start=$( date +%s )


while : ; do


  elapsed=$((  $( date +%s )  - $start ));

  # echo $elapsed
  printf "$( date -d@${elapsed} -u +%H:%M:%S)\r"

  sleep 0.1
done

ミリ秒も計算したいよね

これだと味気ないので、bashで少数を計算する方法と、ミリ秒の表示を組み合わせる。

bashで少数を計算する

bashexpr$(( / (( でも整数値の計算しかできないので、bcなどを使う。

## bc を使って小数点を含む計算をする
echo 0.32 + 0.22 | bc
## 0.0x 始まりにする
printf %03f $( echo 0.32 + 0.22 | bc )

ミリ秒を表示する

date コマンドでミリ秒表示

date +%s.%3N

これらも組み合わせる

タイマー改良

#!/bin/bash

start=$( date +%s.%N )


while : ; do 


  elapsed=$( printf "%0.3f" $( echo   $( date +%s.%N )  - $start | bc  ));

  # echo $elapsed
  printf "$( date -d@${elapsed} -u +%H:%M:%S.%3N )\r"

  sleep 0.1
done

サンプル

実際にタイマーを動かしてみたサンプル

f:id:takuya_1st:20180815210230g:plain

誤差

sleep しているだけなので、だいぶ誤差が出てきます。誤差を正確に扱ってタイマーを作るのは大変なので、コレくらいにとどめておくことにする。

参考資料