who コマンド
UNIX 系のシステムでの基本コマンド who の模造品です。
ログインしている状況を示す utmp ファイルの情報をとりだしています。
デフォルトの who コマンドの出力と、
オプションとして「-i」または「-u」による IDLE TIME の表示をサポートしています。
オプション 意味 -u または -iIDLE 時間の表示
$ who.rb tetsu tty1 May 10 20:35 tetsu ttyp0 May 10 20:35 (:0.0) tetsu ttyp1 May 10 20:40 (:0.0) tetsu ttyp2 May 10 20:40 (:0.0) $ who.rb -u tetsu tty1 May 10 20:35 09:04 tetsu ttyp0 May 10 20:35 . (:0.0) tetsu ttyp1 May 10 20:40 00:20 (:0.0) tetsu ttyp2 May 10 20:40 02:45 (:0.0)
Web ブラウザでの表示上は Ruby のスクリプトですが、HTML の特殊文字をエスケープしています。 テキストとしてセーブしてご利用ください。
#! /usr/local/bin/ruby
# /home/tetsu/src/ruby/toolbox/who.rb
# Created: May 11,1999 Tuesday 04:21:55
# Author: tetsu(WATANABE Tetsuya)
# $Id: who.rb,v 1.4 2003/05/08 03:09:53 tetsu Exp $
# usage:
def idle_time(dev)
t = Time.now - File.atime('/dev/' + dev)
d = 0
if t <= 59
' . '
else
if t > 24 * 3600
d = t / (24 * 3600)
t %= 24 * 3600
end
h = t / 3600
m = t % 3600 / 60
if d == 0
format('%02d:%02d ', h, m)
else
format('%d+%02d:%02d ', d, h, m)
end
end
end
def usage
STDERR.print("usage: #{$0} [-u] [-i]\n")
exit 1
end
TYPE_IN = 0
LINE_IN = 3
NAME_IN = 5
HOST_IN = 6
TIME_IN = 10
UTMP = '/var/run/utmp'
UTMP_FMT = 'ssiA32A4A32A256ssllliiiiA20'
UTMP_LEN = 384
opt_u = false
while ARGV[0] =~ /^-/
case ARGV.shift
when /u/, /i/
opt_u = true
else
usage
end
end
utmp = File.open(UTMP)
while utmp_line = utmp.read(UTMP_LEN)
arr = utmp_line.unpack(UTMP_FMT).values_at(TYPE_IN, NAME_IN, LINE_IN, HOST_IN, TIME_IN)
key = arr[2]
case arr.shift
when 7 # USER_PROCESS
printf("%-8s %-8s %s %s\n",
arr[0],
arr[1],
Time.at(arr[3]).strftime('%b %d %H:%M'),
if opt_u
idle_time(arr[1])
else ''
end + if arr[2] == '' then '' else '(' + arr[2] + ')' end
)
end
end
utmp.close
exit
どこかと同じような内容なのですが...
who コマンドは、データファイルになる /var/run/utmp の形式に依存しています。
この形式の定義は /usr/include/utmp.h にあります。
この定義をもとにデータをとりだすための unpack の定義を決めます。
これを手作業で実施すると大変なので、pstruct というコマンドを利用します。
これは、Perl システムが提供するコマンド(Perl スクリプト)ですが、utmp ファイルの「utmp 構造体」の形式を確認しやすくなります。
Ruby スクリプト中で使用している、構造体の大きさ(UTMP_LEN)や unpack のフォーマット(UTMP_FMT)などを、この情報をもとに決めています。
この pstruct というツールは、便利ですね。
ファイルフォーマットの情報がわかり、データを扱えるようになったらログインしている状況を who コマンドと同じように扱えるようにします。
「ユーザ名」、「ターミナルデバイス」、「ログイン時間」、「どこから接続しているか」などの情報です。
今回は、オプションとして IDLE TIME (-i, -u) をサポートしています。
この情報を得るためにターミナルデバイスのアクセス時間と現在時間の比較を行っています。
同じような内容を扱っている
「
last コマンドを作る Linux glibc version
」
も参考にしてください。