last
特定のユーザーの最後のセッション時間を取得するには、次のコマンドを使用します。
last -aiF -n 1 fakeuser
このコマンドの出力は次のようになります。
fakeuser pts/0 2018年11月27日火曜日11:03:19 - 2018年11月27日火曜日11:14:57 (00:11) 999.999.99.999
私の質問はセッション時間((00:11)
例では)についてです。この時間を秒単位で設定する方法はありますか?
ログイン時間とログアウト時間に基づいて計算できることはわかっていますが、そのコマンド項目でもネットワーク上に何も見つからなかったlast
ため、コマンドから直接ソリューションを探しています。man
参考までに、私はDebian 9.5を使用していますが、その解決策のいくつかはすべてのディストリビューションで動作すると確信しています。
完全な回答に関する追加の質問(ここで最初の回答の後に確認しました):1分未満のセッションを識別する方法は?
答え1
私が正確に覚えているなら、興味のあるフィールドは一般的にフォーマットであり、秒にDays+HH:MM
変換するには、次のようにします。
last -aiF -n 1 fakeuser | \
awk '{gsub(/\(|\)/, "", $14); print $14}' | \
awk -F'[:+]' 'length($0) != 0 {if(length($3) == 0) {$3=$2; $2=$1; $1=0} {print ($1 * 86400) + ($2 * 3600) + ($3 * 60)}}'
最初の行はコマンドですlast
。
2行目は、コマンド出力で必要なフィールドを区別します(フィールド14で示されています)。
3行目にはすべての操作が含まれます。-F
プラス記号(+
)とコロン()からフィールドを分割するには、区切り記号()を設定します:
。次に、行が空でないことをテストします(length($0) != 0
)。次のビット(if(length($3) == 0) {$3=$2; $2=$1; $1=0}
)は、すべての行を日、時間、分の3つのフィールドに正規化する簡単な方法です。残り({print ($1 * 86400) + ($2 * 3600) + ($3 * 60)}
)はただ秒に換算したもの(1日は86400秒、1時間は3600秒、1分は60秒)。
おそらくより簡単な方法があります。しかし、これは私が昼食時にこの問題に取り組んで考えたものです。
答え2
この問題に対するGracefulRestartのawkソリューションは素晴らしいです。答えの説明で指摘したように、コマンドはlast
十分に詳細ではありません。しかし、auth.log
Debianの状況が私がUbuntuで見たものと十分に似ていると仮定すると、そこにあるデータに基づいていくつかの計算を実行できます。
ありがとうこれ答えではありませんが、それでも役に立ちます。
/var/log/auth.log
ローカルログインとSSHログインの両方を含む複数行をフィルタリングしました。
cat auth.log
2018-12-06T07:28:00.487714+13:00 server systemd-logind[944]: New session 2597 of user tink.
2018-12-06T08:34:16.360766+13:00 server login[29537]: pam_unix(login:session): session opened for user tink by LOGIN(uid=0)
2018-12-06T08:34:16.372714+13:00 server systemd-logind[944]: New session c4 of user tink.
2018-12-06T08:34:20.960596+13:00 server login[29537]: pam_unix(login:session): session closed for user tink
2018-12-06T08:36:01.197712+13:00 server systemd-logind[944]: Removed session 2597.
これは(複雑な)awkスクリプトです。
cat session.awk
{
if( $0 ~ /systemd-logind.+New session/ && $0~user ){
start[$6]=$1
}
if( $0 ~ /systemd-logind.+ Removed session/ && start[gensub(/([0-9]+).*/, "\\1", "1", $6)] != "" ){
tmp = start[gensub(/([0-9]+).*/, "\\1", "1", $6)]
cmd = "date +%s -d ";
cmd $1 | getline outa;
cmd " " tmp | getline ina;
close( cmd )
printf "%s was logged in for %s seconds\n", user, outa-ina
}
if( $0 ~ /login.+ session opened/ && $0~user ){
start[gensub(/[^0-9]+([0-9]+).*/,"\\1","1",$3)]=$1
}
if( $0 ~ /login.* session closed/ ){
tmp = start[gensub(/[^0-9]+([0-9]+).*/,"\\1","1",$3)]
cmd = "date +%s -d ";
cmd $1 | getline outa;
cmd " " tmp | getline ina;
close( cmd )
printf "%s was logged in for %s seconds\n", user, outa-ina
}
}
上記のコードスニペットに対してこのコードを実行してください。
awk -v user=tink -f session.awk sessions
tink was logged in for 4 seconds
tink was logged in for 4081 seconds