知道有多少用户在上周已连接到我的电脑,有多少时间已经连接每一个 [英] Know how many users have connected to my computer in the last week, and how many time has been connected each one

查看:129
本文介绍了知道有多少用户在上周已连接到我的电脑,有多少时间已经连接每一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个脚本知道有多少用户在上周已连接到我的电脑,有多少时间已连接每一个。
我可以用最后一个命令,并筛选具有AWK,而是如何在时间列?
我就一定得接在上周每个用户和计算有多少的连接是有过,并且所有连接的总时间。
任何帮助吗?

我得到这样的:

 在'最后一个用户| AWK'{打印$ 1}'|排序-u`;做
    回声CONEXIONES德$ USER:
    最后| grep的$ USER |厕所-l
    #但我需要T细胞计数只剩下最后一周,总打印时间
DONE


解决方案

我强烈反对解析的输出末页,因为它的输出可能实现不同实施和解析登录/注销日期很容易出错。此外,它似乎几乎所有的实现不支持 -F 或类似的哪些没有你就彻底没戏了,因为你需要的年份信息。从理论上讲,你可以检查是否有从一个月到另一个是连续两行更近(如Jan->十二月将表明一年的变化)的一个飞跃,但这种试探是有缺陷的 - 你不能猜出正确的年份(S)正确。例如,以罕见的情况下,没有人登录了一年。

如果你绝对要/要分析它的输出无论哪种方式,不要只庆典/ awk的/剪切做到这一点/ ......以上的原因。要获取会话持续时间,你要么必须解析prettyprinted登入/登出日期自己或已计算的持续,这也是prettyprinted,可能从实现不同实施(如,它不只是时间和分钟。怎样才能达到天/周/年再在该列psented $ p $?)。
只有庆典这样做/ AWK将是一场噩梦,甚至更容易破损比我下面的脚本 - 请不要这么做。

最好的和最哈克的解决方案将涉及编写的 wtmp文件数据直接运营一个小的C程序或脚本(男人wtmp文件),但那么你就必须自己计算的基础上登录/注销对会话持续时间(你不免费获得此,登录是一个记录,注销是第二个)。请参见 busybox的末页实施有关如何读取它的东西的参考。这是去,如果你想这样做的正确的方式的方式。

话虽这么说,我想出了quick'n'dirty(perl的)下面的解决方案。它不运行末页命令,你必须给它自己正确的输入,否则会发生爆炸。如果你的末页输出比我看起来不一样,不支持 -F 日期: :解析无法解析格式的末页命令打印时,也会发生爆炸。有很多改进的余地,但这应该让你开始。

注释


  • -F 需要末页打印日期满(我们需要这个来获得一年,否则我们不能从它的输出决定适当的时间戳)

  • -i 最后告诉输出IP地址,它只是使输出更易于解析

  • 不解析会话持续时间列,而是两者登录/注销日期,将它们转换为划时代的时间,并计算出差异来获取会话持续时间。有参与解析比使用日期::解析,这意味着它必须排除那些没有正确的登录/注销所有会话的其他日期,没有其他的魔法日期(即他们仍然是会员或他们的会话终止,得到了由于重启,死机等),因此,这些会议将不会计算输出的一部分!

  • 默认为7天,但您可以用 -d 开关在命令行上改变这种

code

 #!的/ usr / bin中/ perl的使用严格的;
使用警告;使用日期::解析;
使用的Getopt ::标准;我们$ opt_d;
getopt的('D');
我的天$ = $ opt_d || 7;
由于=时间()我$ - (60 * 60 * 24 * $天);我%的数据;
而(小于&GT)
{
    终日啃食;
    接下来,如果/ SSH |重启|下载|崩溃|仍记录在/;
    #最后-Fi给出了这样的对我的盒子
    #用户名行IP周一4月1日18点17分49秒2013 - 周二4月2日一时00分45秒2013(06:42)
    我($用户,民主基金,民主基金,$ date_from,$ DATE_TO)= / ^(\\ S +)\\ S +(\\ S +)\\ S +([0-9] +)\\ S +([[:alnum:]:\\ S] +)\\ S + - \\ S +([[:alnum:]:\\ S] + [^ \\ S])\\ S + \\(+ \\)/;    我的$ time_from = str2time($ date_from);
    最后,如​​果$ time_from< $以来;
    我的$ time_to = str2time($ DATE_TO);    $数据{$用户} {伯爵} ++;
    $数据{$用户} {持续时间} + = $ time_to - $ time_from;    #打印$用户| $线| $ IP | $ date_from | $ DATE_TO \\ N的;
}打印登录历史的最后几天$一天(S):\\ n \\ n;如果(键%的数据大于0)
{
    我的foreach $用户(键%的数据)
    {
        我的$长度= $ {数据$ USER} {持续时间};
        printf的%S已登录在%d时间(s),共%d日(S),%d个小时(S),而%d分钟的\\ n,
            $用户,
            $数据{$用户} {算},
            ($持续时间/(24 * 60 * 60)),
            ($持续时间/(60 * 60))%24,
            ($时间/ 60)%60,
    }
}
其他
{
    在指定的时间段\\ n在没有登录打印;
}

用法示例

  $最后-Fi | ./last_parse.pl -d 700
登录历史记录的最后700天(S):根被记录在25个时间(s)为一共有36天(S),12个小时可和35分钟的
foob​​ar的被记录在362时间(s)一共有146个天(S),17个小时可和17分钟的
QUUX被记录在3次(个),共有0天(S)0时(S)和4分钟的
$

I need a script to Know how many users have connected to my computer in the last week, and how many time has been connected each one. I can use "last" command and filter the time columns with "awk", but How? I would have to get each user connected in the last week and calculate how many connections it have had, and the total time of all connections. Any help?

I get this:

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

解决方案

I strongly advise against parsing the output of last, as its output may differ from implementation to implementation and parsing the login/logout dates is prone to error. Also, it seems that nearly all implementations don't support -F or similar which without you are completely out of luck, as you need the year information. In theory you could check if there is a leap from one month to another one that is more recent on two consecutive lines (e.g. Jan->Dec would indicate a year change), but this heuristic is flawed - you just cannot guess the correct year(s) correctly. For example, take the rare case that nobody logged in for a year.

If you absolutely have to/want to parse its output either way, don't do it with just bash/awk/cut/... for the reasons above. To get the session duration you would either have to parse the prettyprinted login/logout dates yourself or the already calculated duration, which is also prettyprinted and probably varies from implementation to implementation (as in, it's not just hours and minutes. How do get days/weeks/years represented in that column?). Doing this with just bash/awk would be a nightmare and even more prone to breakage than my script below - please don't do it.

The best and least hacky solution would involve writing a small C program or script that operates on the wtmp data directly (man wtmp), but then you would have to calculate the session durations yourself based on login/logout pairs (you don't get this for free; login is one record, logout is a second one). See busybox' last implementation for a reference on how it reads its stuff. This is the way to go if you want to do it the right way.

That being said, I came up with the quick'n'dirty (perl) solution below. It doesn't run the last command, you have to feed it proper input yourself, otherwise it will explode. If your last output looks different than mine, doesn't support -F or Date::Parse cannot parse the format your last command prints, it will also explode. There is lots of room for improvement, but this should get you started.

Notes

  • -F is required for last to print full dates (we need this to get the year, otherwise we cannot determine proper timestamps from its output)
  • -i tells last to output IP addresses, which just makes its output easier to parse
  • it does not parse the session duration column but rather both login/logout dates, converts them to epoch time and calculates the diff to get the session duration. There is no other magic involved in parsing the dates other than using Date::Parse, which means that it has to exclude all sessions that don't have a proper login/logout date (i.e., they are still logged in or their session got terminated due to a reboot, crash, etc.), so these sessions won't be part of the calculated output!
  • it defaults to 7 days, but you can change this on the command line with the -d switch

Code

#!/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";
}

Example usage

$ 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)
$

这篇关于知道有多少用户在上周已连接到我的电脑,有多少时间已经连接每一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆