flatlineの日記

カレンダー
2010 | 02 | 03 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 04 | 06 | 08 | 09 | 10 | 12 |
2015 | 05 | 06 |
2016 | 07 |

2011-04-17

マシン起動時からの経過秒数をhuman-readableな時刻に変換するワンライナー 15:37

例えば dmesg(1) を打つと時刻表示はマシン起動時からの経過秒数になってて*1,注目している事象が起きたのがいつなのか直感的に分かり辛い.そんなときにとりあえずどうするか.例えば,

[1023695.512464] dpkg[32324]: segfault at 10014 ip 080527e8 sp bfdd71f8 error 6 in dpkg[8048000+32000]

この "1023695" をコピペして,

$ date --date @$(($(date --date "`cut -d. -f1 /proc/uptime` seconds ago" +%s) + 1023695 ))
201149日 土曜日 15:18:40 JST

分かりやすくなった.

説明:

  • 例えば date --date '1234 seconds ago' とすると,現在時刻から 1234 秒前の時刻を入力に設定できる
  • /proc/uptime からは,空白区切りで「起動時からの経過秒数」と「起動時からの累積idle秒数」が得られる.どちらも小数表示なので,前者の小数点より前だけを cut(1) で切り出す
  • date +%s とすると,出力時刻の書式をEpochからの経過秒数に設定できる
  • 例えば date --date @1023695 とすると,Epochからの経過秒数で入力時刻を設定できる(この例では Epoch + 1023695 秒)

発展形として dmesg のラッパを作ってしまうことも考えられる.^[\d+.\d+] のパターンを認識して勝手に上記のような変換を施すスクリプトRubyか何かで書くのだ.まぁでも,当面は手動で十分かな...

と言うか,どっかにもっと簡単な方法は無いのかな?

追記:全部Bashでラッパを作るには,例えば:

$ dmesg|tail -5
[   12.944753] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[   23.648023] eth0: no IPv6 routers present
[  118.304654] EXT4-fs (sda6): re-mounted. Opts: errors=remount-ro,commit=0
[  118.374839] EXT4-fs (sda7): re-mounted. Opts: commit=0
[  118.413960] EXT4-fs (sdb2): re-mounted. Opts: commit=0

これが

$ d1=`cut -d. -f1 /proc/uptime`; dmesg|tail -n5|while read l; do l1=${l%%.*}; date --date "$[$d1 - ${l1:1}] seconds ago" +"[%x %X]${l#*]}"; done
[2011年08月18日 07時19分51秒] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[2011年08月18日 07時20分02秒] eth0: no IPv6 routers present
[2011年08月18日 07時21分37秒] EXT4-fs (sda6): re-mounted. Opts: errors=remount-ro,commit=0
[2011年08月18日 07時21分37秒] EXT4-fs (sda7): re-mounted. Opts: commit=0
[2011年08月18日 07時21分37秒] EXT4-fs (sdb2): re-mounted. Opts: commit=0

となる.手抜きのため, dmesg(1) の出力内に date(1) の書式文字として解釈できる %○○ があると腐るが... まぁ直したかったら直して.

*1LinuxカーネルビルドオプションCONFIG_PRINTK_TIME=y になってるのを仮定.こうすると printk でリング・バッファに出したメッセージにそのような経過秒数が付加される.最近はほとんどそうなってるんじゃないかな.

flalinflalin 2012/09/29 21:46 うげげ,マシンをスリープ(or ハイバネ)にして復帰した後は,uptimeの値が「最初の起動時からの経過時刻」とずれるので,上記ワンライナーは使えないですね...

トラックバック - http://d.hatena.ne.jp/flalin/20110417/1303025836
リンク元