Ask Dave Taylor
  • Facebook
  • Instagram
  • Linkedin
  • Pinterest
  • Twitter
  • YouTube
  • Home
  • Videos
  • Most Popular
  • Top Categories
  • Books
  • About Dave
  • Ask Me
  • > Donate <
  • Home
  • Linux Shell Script Programming
  • Shell script: How long someone’s been logged in?

Shell script: How long someone’s been logged in?

March 2, 2016 / Dave Taylor / Linux Shell Script Programming / 3 Comments

My boss wants to have a simple tool that lets her quickly see how long someone’s been logged in to our Linux server. I figure a quick shell script, but I’m not sure how to code it. Note: Everyone has to log out at the end of the day, so it’s always going to be no more than 8 hours.

Haven’t had a shell script programming question for a while so it’s a pleasure to dig in and figure out how to solve this with a short program. For those of you who don’t know, Unix and Linux systems have a command line programming environment built around the interactive login shell, hence the name “shell script”. In fact, Mac OS X systems also have a command line and the ability to run full shell scripts, a handy capability that I explore in my brand new book Learning Unix for Mac OS X, actually!

Anyway, you present an interesting problem but fortunately frame it a way that makes the calculation considerably easier: Where a script of this nature gets difficult is when users might have been logged in for days, weeks or months.

For your script, there are two data points we need to figure out time on system: the exact time that the user logged in to the system and the current time. We’re going to assume that both are on the same date, so people aren’t logging in at 11pm for 4 hours, for example.

A user’s login time comes from the who command. Like this:

$ who
taylor   console  Mar  1 07:00 
smith    ttys000  Mar  1 08:15

The first task, therefore, is isolating an individual user’s login information, then extracting the time when they logged in (above, taylor logged in at 7:00 and smith logged in at 8:15). Since there’s no am/pm indicated, it’s safe to conclude that this is a 24 hour clock, so logging in at 8:15pm produces a display of 20:15 in this context.

Isolating an individual line involves the use of grep, but be careful, you’ll want to have a complex pattern otherwise a search for “t” will match both taylor and smith. Here’s the pattern we’ll use, with $1 representing the desired login name: “^$1 “. You left-root the pattern with the ‘^’ and require it to have a space appended, ensuring that it’s also the end of the name too (so “smit” doesn’t match “smith”).

Extracting the hour and minute is a bit more tricky because we’ll need to isolate the time field, then break it up into its component parts. This can be done with cut. First, to get the login time:

who |  grep "^$1 " | cut -d\  -f5

The result of that for $1 being set to “smith” would be 08:15. Breaking that up further is another use of cut, but this time with a different field delimiter, the colon. To get just the login hour, for example:

 ... | cut -d: -f1

Since all of this needs to happen within a shell script, it makes the most sense to assign these as two variables we’ll call “lhour” and “lmin” for login hour and login minute, respectively. That ends up looking like this:

login=$(who | grep "^$1 " | head -1)

lhour=$(echo $login | cut -d\  -f5 | cut -d: -f1)
 lmin=$(echo $login | cut -d\  -f5 | cut -d: -f2)

linux penguin, shell script programming scriptingNotice I slipped something else in too, the head -1 in the first variable assignment. The purpose of that first line is to ensure that the hour and minute are extracted from the same matching line produced by who, just in case the user might log out during execution of the script. It’s also slightly faster because the who|grep only needs to happen once, not twice.

Now the easier part, getting the current hour and minute. Those can both be done by using output formats to the date command, fortunately:

hour=$(date +%H)
min=$(date +%m)

Which means now it’s just math. Elapsed time is the current time minus the login time, which can be calculated a couple of ways. I’m going to be lazy and simply subtract login hour from base hour and login minute from base minute:

elapsed_hours=$(( $hour - $lhour ))
elapsed_mins=$(( $min - $lmin ))

The problem with this solution is that what if they logged in at 9:45 and it’s now 10:00? 10-9 = 1, and 0-45 = -45, which is a bit confusing because they haven’t been logged in for 1 hour and -45 minutes. Well, sort of they have, though, because a negative value for elapsed minutes means that it’s less than the current hour calculation, so 1 hour – 45 minutes = 15 minutes, which is correct.

This can be codified in the script thusly:

if [ $elapsed_mins -lt 0 ] ; then
   elapsed_mins=$(( $elapsed_mins + 60 ))
   elapsed_hours=$(( $elapsed_hours - 1 ))
fi

So that indeed we subtract 1 hour frmo the elapsed hours and normalize the elapsed minutes by adding 60 (so that -45 + 60 = 15, for example).

All that’s left now is to offer up some useful output:

echo "User $1 logged in at ${lhour}:$lmin, and it's currently ${hour}:$min"
echo "Elapsed login time is $elapsed_hours hours and $elapsed_mins minutes"

So there you have it. Now it’s up to you to copy and paste all the individual blocks to get a fully functional shell script to keep your boss happy. 🙂

Let’s Stay In Touch!

Never miss a single article, review or tutorial here on AskDaveTaylor, sign up for my fun weekly newsletter!
Name: 
Your email address:*
Please enter all required fields
Correct invalid entries
No spam, ever. Promise. Powered by FeedBlitz
Please choose a color:
Starbucks coffee cup I do have a lot to say, and questions of my own for that matter, but first I'd like to say thank you, Dave, for all your helpful information by buying you a cup of coffee!
linux programming, linux shell scripts, mac shell programming, shell script programming, shell scripting, shell scripts, unix programming, unix shell, unix shell scripts

3 comments on “Shell script: How long someone’s been logged in?”

  1. kjteoh says:
    July 29, 2016 at 5:37 pm

    Saw this yesterday and printed :

    last -F on linux. Also very helpful is ac -d -p . Milege will vary when you’re on Linux, MacOS and UNIX.

    Cheers.

    Reply
  2. kjteoh says:
    July 29, 2016 at 5:07 am

    on linux … last -F

    Reply
  3. Erik says:
    March 23, 2016 at 12:20 pm

    Great post. One note… For this to work on my Mac I had to tweak your current minutes statement to use a +%M for minutes. The +%m was pulling the calendar month (3) for me when run today (3/23/16).

    Thanks,
    Erik

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Search

Recent Posts

  • Can I Have Microsoft Edge Suggest Strong Passwords?
  • How Can I Password Protect Tax Forms Sent Via Email?
  • Easy Way to Add Emoji to Tweets from a Web Browser?
  • How Do You Post Multiple Photos in Instagram?
  • How Can I Change the Default Search Engine in Google Chrome to Microsoft Bing?

On Our YouTube Channel

DIGDIY BUDGET ANC TWS Earbuds [D10WH] -- REVIEW

Rush Charge Hinged Smartphone Battery Stand -- UNBOXING & REVIEW

Categories

  • AdSense, AdWords and PPC Help (106)
  • Amazon Echo & Kindle Help (79)
  • Amazon, eBay and Online Shopping Help (157)
  • Android Help (158)
  • Apple Watch Help (49)
  • Articles, Tutorials and Reviews (326)
  • Business Advice (191)
  • Computer and Internet Basics (714)
  • d) None of the Above (160)
  • Facebook Help (364)
  • Google & Gmail Help (154)
  • HTML and Web Design (243)
  • Instagram Help (43)
  • iPad Help (136)
  • iPhone Help (570)
  • LinkedIn Help (79)
  • Linux Help (147)
  • Linux Shell Script Programming (86)
  • Mac & MacOS Help (830)
  • Most Popular (10)
  • MP3 Player Help (181)
  • Outlook & Office 365 Help (9)
  • PayPal Help (68)
  • Pinterest Help (53)
  • Reddit Help (11)
  • SEO & Marketing (80)
  • Spam, Scams & Security (82)
  • Trade Show Updates (23)
  • Twitter Help (212)
  • Video Game Tips (66)
  • Web Site Traffic Tips (62)
  • Windows 10 Help (825)
  • Wordpress Help (201)
  • Writing and Publishing (72)
  • YouTube Help (43)
  • YouTube Video Reviews (159)
  • Zoom, Skype & Video Chat Help (40)

Archives

Social Connections:

Ask Dave Taylor


Follow Me on Pinterest
Follow me on Twitter
Follow me on LinkedIn
Follow me on Instagram


AskDaveTaylor on Facebook



microsoft insider mvp


This web site is for the purpose of disseminating information for educational purposes, free of charge, for the benefit of all visitors. We take great care to provide quality information. However, we do not guarantee, and accept no legal liability whatsoever arising from or connected to, the accuracy, reliability, currency or completeness of any material contained on this site or on any linked site. Further, please note that by submitting a question or comment you're agreeing to our terms of service, which are: you relinquish any subsequent rights of ownership to your material by submitting it on this site. Our lawyer says "Thanks for your cooperation."
© 2020 by Dave Taylor. "Ask Dave Taylor®" is a registered trademark of Intuitive Systems, LLC.
Privacy Policy - Terms and Conditions - Accessibility Policy