知道最近一周有多less用户连接到我的电脑,以及每个用户连接了多less时间

我需要一个脚本,显示哪些用户在上周连接到我的电脑的概要以及频率。

我知道我可以使用last ,用awk过滤时间列,但是如何? 我将不得不让每个用户在上周连接,并计算连接数加上所有连接的总时间。 这是我到目前为止所提出的:

 for USER in `last | awk '{print $1}' | sort -u`; do echo "Conexiones de $USER:" last | grep $USER | wc -l # BUT I NEED T COUNT ONLY LAST WEEK AND PRINT TOTAL TIME done 

我强烈建议不要分析last的输出,因为它的输出可能因实现而异,并且解析登录/注销日期很容易出错。 另外,似乎几乎所有的实现都不支持-F或类似的,没有你是完全不幸的,因为你需要年份信息。 从理论上讲,你可以检查是否有从一个月到另一个连续两行的更新(如1月 – > 12月会显示年度变化),但这种启发式是有缺陷的 – 你不能猜测正确的一年(s)正确。 例如,拿一个没有人登录一年的罕见案例。

如果你绝对必须/想分析它的输出,不要只用bash / awk / cut / …来解决上述的问题。 要获得会话持续时间,您必须自己解析已打印的登录/注销日期,或者已经计算的持续时间,这个时间也是打印的,可能因实现而有所不同(因为这不仅仅是小时和分钟)。 /周/年表示在那一栏?)。 这样做只是bash / awk将是一个噩梦,甚至比我的脚本更容易破损 – 请不要这样做。

最好的和最简单的解决方案将涉及到编写一个小的C程序或脚本,直接对wtmp数据进行操作( man wtmp ),但是您必须根据登录/注销对自己计算会话持续时间(您没有这是免费的;登录是一个记录,注销是第二个)。 请参阅busybox的last实现以获取有关如何读取其内容的参考。 如果你想以正确的方式做到这一点,这是一条路。

这就是说,我提出了下面的quick'n'dirty(perl)解决方案。 它不运行last命令,你必须自己给它正确的输入,否则会爆炸。 如果你的last输出和我的看起来不一样,不支持-F或者Date::Parse不能解析你last命令打印的格式,它也会爆炸。 有很多改进的空间,但这应该让你开始。

笔记

  • -Flast打印完整日期所必需的(我们需要这个来得到年份,否则我们不能从它的输出中确定适当的时间戳)
  • -i告诉最后输出IP地址,这只是使其输出更容易解析
  • 它不解析会话持续时间列,而是解析登录/注销日期,将它们转换为纪元时间并计算差异来获得会话持续时间。 除了使用Date::Parse ,没有其他的解释日期的魔法,这意味着它必须排除没有正确的登录/注销日期的所有会话(即,他们仍然登录或他们的会话得到由于重新启动,崩溃等终止), 所以这些会话将不会成为计算输出的一部分!
  • 它默认为7天,但您可以在命令行上使用-d开关进行更改

 #!/usr/bin/perl use strict; use warnings; use Date::Parse; use Getopt::Std; our $opt_d; getopt('d'); my $days = $opt_d || 7; my $since = time() - (60 * 60 * 24 * $days); my %data; while (<>) { chomp; next if /ssh|reboot|down|crash|still logged in/; # last -Fi gives this on my box # username line ip Mon Apr 1 18:17:49 2013 - Tue Apr 2 01:00:45 2013 (06:42) my ($user, undef, undef, $date_from, $date_to) = /^(\S+)\s+(\S+)\s+([0-9.]+)\s+([[:alnum:]:\s]+)\s+-\s+([[:alnum:]:\s]+[^\s])\s+\(.+\)/; my $time_from = str2time($date_from); last if $time_from < $since; my $time_to = str2time($date_to); $data{$user}{"count"}++; $data{$user}{"duration"} += $time_to - $time_from; # print "$user|$line|$ip|$date_from|$date_to\n"; } print "login history for the last $days day(s):\n\n"; if (keys %data > 0) { foreach my $user (keys %data) { my $duration = $data{$user}{"duration"}; printf "%s was logged in %d time(s) for a total of %d day(s), %d hour(s) and %d minute(s)\n", $user, $data{$user}{"count"}, ($duration / (24 * 60 * 60)), ($duration / (60 * 60 )) % 24, ($duration / 60 ) % 60, } } else { print "no logins during the specified time period\n"; } 

用法示例

 $ last -Fi | ./last_parse.pl -d 700 login history for the last 700 day(s): root was logged in 25 time(s) for a total of 36 day(s), 12 hour(s) and 35 minute(s) foobar was logged in 362 time(s) for a total of 146 day(s), 17 hour(s) and 17 minute(s) quux was logged in 3 time(s) for a total of 0 day(s), 0 hour(s) and 4 minute(s) $ 

尝试这个

脚步

  1. last > login.txt

  2. last | awk '{print $3}' | sort -u > names.txt

  3. 从names.txt中迭代每行,并应用grep "line1" login.txt | wc -l grep "line1" login.txt | wc -l

你会得到每个用户的计数(每个用户是在names.txt每行)