获取上次会话的时间(以秒为单位)

获取上次会话的时间(以秒为单位)

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

如果我没记错的话,您感兴趣的字段通常采用格式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命令。

在第二行中,我们将您想要的字段从命令输出中分离出来,该字段似乎是字段 14。

第三行包含所有动作。设置分隔符 ( -F) 以在加号 ( +) 和冒号 ( :) 上分割字段。然后我们进行测试以确保该行不为空 ( length($0) != 0)。下一位 ( if(length($3) == 0) {$3=$2; $2=$1; $1=0}) 是一个快速技巧,可将任意行标准化为三个字段:天、小时和分钟。剩下的 ( {print ($1 * 86400) + ($2 * 3600) + ($3 * 60)}) 只是转换为秒(一天 86400 秒,一小时 3600 秒,一分钟 60 秒)。

可能有一种更简单的方法,但这是我在午餐时搞乱这个问题时想到的。

答案2

GracefulRestart 对这个问题的 awk 解决方案非常出色;正如您在对他的回答的评论中指出的那样,该last命令不够精细。但是,假设auth.logdebian 上的情况与我在 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

相关内容