Linux – List of all the users that logged in using GUI or Command Line

bashlinuxUbuntuubuntu 12.04

I need to calculate the total time that a specific user stay logged in per day. And stop user using the computer more than the time allowed by shutting down the system.

uptime cannot be used since this is a multiuser computer

last command is not doing the job, because, as I observed, it only store data of users who run the terminal. If a user logged in using GUI and continue to use the computer without running the terminal an entry is not written to /var/log/wtmp.

Is there a way to find the information I need?
I am using Ubuntu 12.04 LTS

Best Answer

who (using /var/run/utmp) should work if the user is logged in via X, too.

Then you can run this script via /etc/crontab every minute. What it does:

  • loop over all users ($u) currently logged in
  • increments the number in /var/log/accounting-$u -- as this is done every minute, the file stores the total time the user $u is logged in so far.
  • check if $u has reached the limit ($allowedtime), here 60 minutes. If so, shutdown the system or whatever. 5 minutes earlier only send a warning (courtesy of @terdon).
  • finally if the user $u wasn't seen for the last 24 hours, delete /var/log/accounting-$u and the game can start from the beginning.

As I mentioned in a comment, I don't think shutting down the system is not such a good idea. Especially with this script, because if a user logs in again while the 24 hours aren't over yet, the shutdown action will be triggered after less than a minute (when the cron starts accounting.sh the next time).


accounting.sh

#!/bin/bash

accountinglogprefix=/var/log/accounting-
allowedtime=60

for u in $(who | cut -d " " -f 1 | sort | uniq); do

  if [[ -e ${accountinglogprefix}${u} ]]; then
    consumed=$(cat ${accountinglogprefix}${u})
  else
    consumed=0
  fi
  echo -n $(( consumed + 1 )) > ${accountinglogprefix}${u}

  if [[ $consumed -gt $allowedtime ]]; then 
    # time is over, do whatever you want
    echo "Shutting down..."
  elif [[ $consumed -gt $(( allowedtime - 5 )) ]]; then
    # notify the user $u that his time is over in 5 minutes with a suitable command
    echo "Time's up! Shutting down in 5 minutes..."
  fi

  # check if e.g. 24h have passed since the user was last seen
  if [[ $(( $(date +%s ) - $(stat -c %Y ${accountinglogprefix}${u}) )) -gt $(( 24 * 3600 )) ]]; then
    rm ${accountinglogprefix}${u}
  fi

done

Note: This is not a fully mature script (i.e. ready for copy & paste) -- it should just demonstrate a different approach.

Related Question