I need a script which shows a summary of which users have connected to my computer during the last week and how often.
I know I can use last
and filter the time columns with awk
, but how?
I would have to get each user connected in the last week and calculate the number of connections plus the total time of all connections.
This is what I have come up with so far:
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
Try this
Steps
last > login.txt
last | awk '{print $3}' | sort -u > names.txt
Iterate each lines from names.txt and apply
grep "line1" login.txt | wc -l
you will get count for each user (each user is each line in names.txt)
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 yourlast
output looks different than mine, doesn't support-F
orDate::Parse
cannot parse the format yourlast
command prints, it will also explode. There is lots of room for improvement, but this should get you started.Notes
-F
is required forlast
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 parseDate::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!-d
switchCode
Example usage