我需要一个脚本,其示出的用户已经在上周多久连接至计算机的摘要。
我知道我可以使用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
或类似的,其没有你就彻底没戏了,因为你需要的年份信息。 从理论上讲,你可以检查是否有从一个月到另一个是连续两行近期(如Jan->十二月将表明一年的变化)的一个飞跃,但这种试探是有缺陷的 - 你不能猜测正确的年份(多个)正确。 例如,采取罕见的情况下,没有人登录了一年。
如果你非得/要分析它的输出无论哪种方式,不要只庆典/ awk的/剪切做到这一点/ ......以上的原因。 要获得会话持续时间,你要么必须解析prettyprinted登录/注销日期自己或已计算的时间,这也是prettyprinted,可能从实现不同实现(如,它不只是小时和分钟。如何获得天/在该列代表周/年?)。 只有庆典/ AWK这样做将是一场噩梦,甚至比我下面的脚本更容易破损 - 请不要这么做。
最好的和最哈克解决方案将涉及编写上运行一个小的C程序或脚本wtmp
的数据直接( man wtmp
),但你必须自己计算基于登录/注销对会话持续时间(你没有得到这个自由;登录是一个记录,注销是第二个)。 见busybox的” last
实现了它如何读取它的东西的参考。 这是去,如果你想要做正确的方式的方式。
话虽这么说,我想出了quick'n'dirty(perl的)下面的解决方案。 它不运行的last
命令,你必须给它自己正确的输入,否则会发生爆炸。 如果你的last
输出比我看起来不一样,不支持-F
或Date::Parse
无法解析格式的last
命令打印时,也会发生爆炸。 有很多改进的余地,但这应该让你开始。
笔记
-
-F
需要last
打印日期满(我们需要这个来获得一年,否则我们无法确定其输出正确的时间戳) -
-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)
$
试试这个
脚步
last > login.txt
last | awk '{print $3}' | sort -u > names.txt
迭代从names.txt中各行及应用grep "line1" login.txt | wc -l
grep "line1" login.txt | wc -l
你会得到数为每个用户(每个用户在names.txt中的每一行)
文章来源: Know how many users have connected to my computer in the last week, and how many time has been connected each one