LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-19-2012, 03:31 PM   #1
vril
LQ Newbie
 
Registered: Apr 2012
Posts: 5

Rep: Reputation: Disabled
total login time of each user in last


Hi everyone. I would like to write a script in bash that displays the total login time of every single user shown by unix "last" command, regardless of any different machines he connects from. How can I achieve that? Thank you.
 
Old 04-19-2012, 07:55 PM   #2
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.8, Centos 5.10
Posts: 17,247

Rep: Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328
Pick your language eg shell, Perl, awk etc, then decide how far back you want to go, then do a trial run with just a few records for test purposes.
Note you'll want to skip no-user entries eg reboot.
What are you going to do if a user has been deleted from the system; will you still count those recs? If not, x-ref against passwd file; might be a good way to skip non-user recs anyway.

Have a go and come back with specific qns and show us your code when you do.

Personally I'd take a copy of the last cmd output rather than pipe it direct into the prog, but that's your call.
 
Old 04-19-2012, 09:21 PM   #3
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Something like this, maybe? At the mention perl I couldn't resist ;}

Code:
#!/usr/bin/perl 
#===============================================================================
#
#         FILE:  last.pl
#
#        USAGE:  last | ./last.pl  
#
#  DESCRIPTION:  Getting the accumulated login times of users
#===============================================================================

use strict;
use warnings;


my %hours;
my %minutes;
my %logins;
my $user;

while (<STDIN>) {   # While we have input...   
  # Find lines and save username, login time 
  if ( /^(\S+).*\((.*)\)/ && !/^reboot/ ) {
    my $hours;
    my $minutes;
    # jump through a hoop if the user was on for longer than 24 hours
    # in one go ... :)
    my @tmp=split(/:|\+/, $2 );
    # Increment total hours, minutes, and logins 
    if( $#tmp < 2){
      # no overnighters 
      $hours{$1} += $tmp[0];
      $minutes{$1} += $tmp[1]
    }else{
      # overnighters
      $hours{$1} += $tmp[0]*24 +$tmp[1];
      $minutes{$1} += $tmp[2]
    }
    $logins{$1}++;
  }
}

# For each user in the array...        
foreach $user (sort(keys %hours)) {
   # Calculate hours from total minutes 
   $hours{$user} += int($minutes{$user} / 60);
   $minutes{$user} %= 60;
   # Print the information for this user 
   print "User $user, total login time ";
   printf "%02d:%02d, ", $hours{$user}, $minutes{$user};
   print "total logins $logins{$user}.\n";
}
 
Old 04-20-2012, 08:31 AM   #4
vril
LQ Newbie
 
Registered: Apr 2012
Posts: 5

Original Poster
Rep: Reputation: Disabled
Guys, sorry but it has to be in bash with use of "last" unix command. Thanks.
 
Old 04-20-2012, 05:06 PM   #5
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Well, take the logic of what perl does, and replicate it in bash.
Should be possible, maybe slightly more verbose.
 
Old 04-22-2012, 04:19 PM   #6
danliston
LQ Newbie
 
Registered: Feb 2012
Location: South Dakota
Distribution: Fedora, CentOS, Oracle, OpenSolaris
Posts: 18

Rep: Reputation: Disabled
#!/usr/bin/bash

# Grab a point in time snapshot of the output from the last command
last > /tmp/last_output

# Alternatively because there are output variances to deal with,
last | grep '+' > /tmp/day_more && last | grep -v '+' > /tmp/day_less

# Now we have complete output of last, and split versions of sessions
# that are shorter or longer than one day. We should convert days in
# the day_more file to hours and append to day_less for consistency.
# placeholder to code this thought process...

# we are not interested in 00 minute entries (unless we also decide to count logins)
# We are not interested in any users that are currently logged in or the wtmp footer
# We are not interested in system entries either. Let's hope no users match our egrep
egrep -v '(00:00|logged|^$|wtmp|system)' /tmp/last_output | sed 's/[()]//g' > /tmp/last_clean
cut -d' ' -f1 /tmp/last_clean | sort -u > /tmp/unique_users

# We can crunch data (output) in several ways; Read a line, test each field, process...
# Or we can break our data into separate outputs (by user) before crunching the data.
for user in $(cat /tmp/unique_users)
do
# Guarantee we are starting each loop with clean variables
minute=0
tm=0
hour=0
th=0
day=0
td=0

for time in $(awk /^${user}/'{print $NF}' /tmp/last_clean)
do
temp=$(echo ${time} | cut -d+ -f1)
if [ ${time} = ${temp} ]; then # The day indicator (+) does not exist
day=0
hour=$(echo ${time} | cut -d: -f1 | sed 's/^0//')
else
day=$(echo ${time} | cut -d+ -f1)
hour=$(echo ${time} | cut -d+ -f2 | cut -d: -f1 | sed 's/^0//')
fi
# We use sed to strip padded 0's in single digit values for math (07 becomes just 7)
minute=$(echo ${time} | cut -d: -f2 | sed 's/^0//')
((td = td + day))
((th = th + hour))
((tm = tm + minute))
done
# We have our column totals, but now we need to normalize the output again
minute=$(expr $tm % 60)
hour=$(expr `echo "$tm / 60 + $th" | bc` % 24)
day=$(expr `echo "$tm / 60 + $th" | bc` / 24 + $td)
printf "%8s %4d + %02d : %02d \n" $user $day $hour $minute
done

# Do I get an A?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
New user can not login and wait for a long time trwu Red Hat 6 07-12-2011 11:29 AM
Disable user login after certain time of day tkmsr Linux - Server 3 12-18-2009 12:01 AM
Why are user credentials not being passed to server at time of login? rajevar Linux - Newbie 2 09-24-2009 04:57 PM
how to get user login time haplo Linux - Newbie 4 02-05-2009 03:01 AM
Changing a user's group at login depending on the time of day Steve2001 Linux - General 10 10-11-2004 04:29 AM


All times are GMT -5. The time now is 10:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration