Page 1 of 1

Parental Control: Limiting computer usage time

Posted: Fri Jul 22, 2011 11:20 am
by Pilosopong Tasyo
Limiting computer usage time: a poor man's attempt at parental control

This tutorial came about due to a question asked in another thread. The whole algorithm was posted over 2 months ago and I was hoping the original poster in that thread wrote back of his progress. Unfortunately that has yet to happen so I can only imagine if that small project ever became a reality.

But anyway, if you are in a situation where, for example:

- multiple users share a single computer
- several of those users are minors, and
- you as the parent/concerned adult wish to limit their daily computer usage time

then this might interest you. The requirements and rules have already been laid out in the other thread, and the script will be based on it albeit there are some slight modifications in key places. I recommend reading the whole thread to get an understanding of what it's all about.

The script itself is short; several if-then-else statements. I made liberal use of comments to document the whole process. To install the script:

Create a text file in your home directory, filename is users_and_times.cfg. This configuration file contains a list of users and their corresponding time limits (in minutes). Below is an example list:

/home/administrator/users_and_times.cfg

Code: Select all

# Configuration file containing usernames
# and their corresponding alloted time.
# Format: <login-name> <allocated minutes>

bob 30
samantha 45
john 60
jess 30
cora 30
candy 15
tony 120
patrick 15
anne 60
Open a terminal window (Mint menu > Terminal).

Code: Select all

gksudo gedit /root/limit-usage-time.sh
Key in your password.

Copy and paste the whole script listed below to the gedit window.

/root/limit-usage-time.sh

Code: Select all

#!/bin/bash

#####
#
# Project       : Poor man's parental control
#                 Limiting a user's daily computer usage time
# Started       : May 12, 2011
# Last Modified : July 22, 2011
# Author        : Anthony David (Pilosopong Tasyo)
# Module        : limit-usage-time.sh
# Description   : Monitors the amount of time a user spends on the computer.
#                 Lock the screen when the limit has been reached.  Run this
#                 script as a cron job (executed once per minute).
#
##########

# Some useful variables
VICTIM=`users`       # Who's currently logged in?
ADMIN=administrator  # ADMIN = login name of the computer's administrator.

# Date- and time-keeping variables.
TODAY=`date +%D`
YESTERDAY=0
TIME_LEFT=0

# Shortcuts to configuration files.
ROLLOVER_DATE_FILE=/root/$VICTIM-rollover-date.cfg
TIME_LEFT_FILE=/root/$VICTIM-time-left.cfg
USERS_AND_TIMES_FILE=/home/$ADMIN/users_and_times.cfg

# STEP ONE
# The entire script relies on the fact that a user must be logged in.
# Any user -- root, the admininstrator, user1, user2, etc. If nobody
# is logged in, the script has nothing to do. So, exit.

# combined with...

# STEP TWO
# The administrator has unlimited access (consequently, so does root),
# thus the script doesn't need to run if admin/root is logged in.

if [ -z "$VICTIM" -o "$VICTIM" == "$ADMIN" -o "$VICTIM" == "root" ]
then
  exit
fi

# STEP THREE
# Check if $VICTIM already have the two configuration files in root's
# directory. If neither one nor both are present, it is assumed that
# $VICTIM is a new user account, so create them on the fly.  Otherwise
# read the files and store the values to variables.

if [ ! -e "$ROLLOVER_DATE_FILE" -o ! -e "$TIME_LEFT_FILE" ]
then
  echo $YESTERDAY > $ROLLOVER_DATE_FILE
  echo $TIME_LEFT > $TIME_LEFT_FILE
else
  YESTERDAY=`cat $ROLLOVER_DATE_FILE`
  TIME_LEFT=`cat $TIME_LEFT_FILE`
fi

# STEP FOUR
# No longer necessary since it's been superseded by
# the else statement in STEP THREE

# STEP FIVE
# If $TODAY and $YESTERDAY do not match, either a new day already has begun
# or STEP THREE happened. If this is the case, re-set the configuration files.

if [ "$TODAY" != "$YESTERDAY" ]
then
  # Find out the allocated time for $VICTIM.  If $VICTIM's not found
  # in the configuration file, defaults to zero.
  TIME_LEFT=`grep $VICTIM $USERS_AND_TIMES_FILE | awk '{print $2}'`
  if [ -z $TIME_LEFT ]
  then
    TIME_LEFT=0
  fi

  echo $TODAY > $ROLLOVER_DATE_FILE
  echo $TIME_LEFT > $TIME_LEFT_FILE  
fi

# STEP SIX
# Remind the VICTIM that he/she has $TIME_LEFT minute(s) left for the day.

sudo -u $VICTIM DISPLAY=:0.0 notify-send -i gtk-info \
  "Reminder:" "You have $TIME_LEFT minute(s) left for the day."

sleep 10  # It takes 10 seconds for notify-send to finish the OSD 

# STEPs SEVEN and EIGHT
# Find out if $VICTIM exhausted the allowed time limit.  If there's still
# $TIME_LEFT, decrease by 1 and store the new value in the configuration file.
# Otherwise lock the screen (or force an ungraceful logout).

if [ $TIME_LEFT -gt 0 ]
then
  TIME_LEFT=`expr $TIME_LEFT - 1`
  echo $TIME_LEFT > $TIME_LEFT_FILE
else
  sudo -u $VICTIM DISPLAY=:0.0 gnome-screensaver-command --activate --lock
  # The command below will force an ungraceful logout -- not recommended!
  # sudo pkill -u $VICTIM
fi

# We're done!

# EOF
Make sure you edit the ADMIN=administrator line and put your login name there instead. Save and close the file.

Make the script executable

Code: Select all

sudo chmod u+x /root/limit-usage-time.sh
Edit root's cron table to run the script every minute

Code: Select all

sudo crontab -e

Code: Select all

# m h  dom mon dow   command
* * * * * /root/limit-usage-time.sh
And you're done. If you're going to add a new user in the future, don't forget to update the users_and_times.cfg file as well. Using the crontab setting listed above, the script will run all year round. If you want to make an exception, for example, run the script during certain hours of the day or during weekdays only, all you have to do is modify the contab to suit your needs.

I hope someone finds this useful. Regards!

PT

Re: Parental Control: Limiting computer usage time

Posted: Fri Jul 22, 2011 11:40 am
by Habitual
Good stuff.

Re: Parental Control: Limiting computer usage time

Posted: Fri Jul 22, 2011 2:26 pm
by dritzominous
Wow! :shock:

I'm so glad I didn't grow up with you as my parent. :lol:

Excellent script though, I learned a lot from that. Thank you!

Re: Parental Control: Limiting computer usage time

Posted: Mon Dec 07, 2015 7:27 pm
by Thomas Baeckeroot
Previous script version was not working fully on my PC, so I modified it.
I aimed to be as generic as possible but I am not sure what is specific to my configuration and what is not.
This script worked fine with Linux Mint 17.1 Xfce (with a configuration that uses more than one X terminal).

I also added an audio warning speaking the time left during the last 5 minutes.

Code: Select all

#!/bin/bash

#####
#
# Project       : Poor man's parental control
#                 Limiting a user's daily computer usage time
# Started       : May 12, 2011
# Last Modified : March, 2015
# Author        : Anthony David (Pilosopong Tasyo)
# Author (minor): Trapovid (aka TPV below) (anonymous but reachable at http://forums.linuxmint.com )
# Module        : limit-usage-time.sh
# Description   : Monitors the amount of time a user spends on the computer.
#                 Lock the screen when the limit has been reached.  Run this
#                 script as a cron job (executed once per minute).
#
# Installation explained at http://forums.linuxmint.com/viewtopic.php?f=213&t=77687
#
# Note from Trapovid:
# Previous script version was not working fully on my PC, so I modified it.
# I aimed to be as generic as possible but I am not sure what is specific to my configuration and what is not.
# This script worked fine with Linux Mint 17.1 Xfce (with a configuration that uses more than one X terminal).
#
##########

# For debuging:
echo -----------------------------------------------------------
echo `date`
echo Running $0 with user $USER
set -x
# To debug a cron job (as this script), we can also inform the cron line with the "2>&1" tag, as per below example:
# * * * * * /root/limit-usage-time.sh >> /tmp/limit-usage-time.log 2>&1


# Some useful variables
ADMIN=thomas  # ADMIN = login name of the computer's administrator.

# Date- and time-keeping variables.
TODAY=`date +%D`
YESTERDAY=0
TIME_LEFT=0

# Shortcuts to configuration files.
USERS_AND_TIMES_FILE=/home/$ADMIN/users_and_times.cfg

# Who's currently logged in:
#VICTIMS=`users`        #TPV: This does not work if other users are connected with 'ssh' for example, also an issue if user launch various terminals...
#VICTIMS=`ps -aux | grep xinitrc | grep -v 'grep\|root\|$ADMIN' | cut -f 1 -d ' '` #TPV: Another solution by extracting user with X session
VICTIMS=`ps -aux | grep wm | grep -v "grep\|root\|$ADMIN" | cut -f 1 -d ' '` #TPV: Another solution by extracting users who started a Window Manager (worked better for me)

# For debuging...
echo Victims are: $VICTIMS

for VICTIM in $VICTIMS; do

	# Shortcuts to configuration files.
	ROLLOVER_DATE_FILE=/root/$VICTIM-rollover-date.cfg
	TIME_LEFT_FILE=/root/$VICTIM-time-left.cfg
	TIME_LEFT_FILE_FOR_USER=/tmp/$VICTIM-time-left.cfg

	# STEP ONE
	# The entire script relies on the fact that a user must be logged in.
	# Any user -- root, the admininstrator, user1, user2, etc. If nobody
	# is logged in, the script has nothing to do. So, exit.

	# combined with...

	# STEP TWO
	# The administrator has unlimited access (consequently, so does root),
	# thus the script doesn't need to run if admin/root is logged in.

	#TPV: Eliminated by the 'grep -v "grep\|root\|$ADMIN"' so it is not needed anymore
	#if [ -z "$VICTIM" -o "$VICTIM" == "$ADMIN" -o "$VICTIM" == "root" ]
	#then
	#  break
	#fi

	# STEP THREE
	# Check if $VICTIM already have the two configuration files in root's
	# directory. If neither one nor both are present, it is assumed that
	# $VICTIM is a new user account, so create them on the fly.  Otherwise
	# read the files and store the values to variables.

	if [ ! -e "$ROLLOVER_DATE_FILE" -o ! -e "$TIME_LEFT_FILE" ]
	then
	  echo $YESTERDAY > $ROLLOVER_DATE_FILE
	  echo $TIME_LEFT > $TIME_LEFT_FILE
	  echo $TIME_LEFT > $TIME_LEFT_FILE_FOR_USER
	else
	  YESTERDAY=`cat $ROLLOVER_DATE_FILE`
	  TIME_LEFT=`cat $TIME_LEFT_FILE`
	fi

	# STEP FOUR
	# No longer necessary since it's been superseded by
	# the else statement in STEP THREE

	# STEP FIVE
	# If $TODAY and $YESTERDAY do not match, either a new day already has begun
	# or STEP THREE happened. If this is the case, re-set the configuration files.

	if [ "$TODAY" != "$YESTERDAY" ]
	then
	  # Find out the allocated time for $VICTIM.  If $VICTIM's not found
	  # in the configuration file, defaults to zero.
	  TIME_LEFT=`grep $VICTIM $USERS_AND_TIMES_FILE | awk '{print $2}'`
	  if [ -z $TIME_LEFT ]
	  then
	    TIME_LEFT=0
	  fi

		echo $TODAY > $ROLLOVER_DATE_FILE
		echo $TIME_LEFT > $TIME_LEFT_FILE 
		echo $TIME_LEFT > $TIME_LEFT_FILE_FOR_USER
	fi

	# STEP SIX
	# Remind the VICTIM that he/she has $TIME_LEFT minute(s) left for the day.

	DISP=`ps -aux | grep wm | grep ^$VICTIM | grep -v grep | tr -s ' ' | cut -f 13 -d ' '`

	# Display a warning message on the victim's screen:
	sudo -u $VICTIM DISPLAY=$DISP notify-send -t 10000 -i gtk-info "Rappel:" "Il te reste $TIME_LEFT minutes pour aujourd hui."
	#  "Reminder:" "You have $TIME_LEFT minutes left for the day."
	#sleep 10  # It takes 10 seconds for notify-send to finish the OSD

	#TPV: Audio play a warning (so that if victim is in a full-screen game, he will hear the message)
	# I got problem 'unable to open slave' with all of: aplay, paplay, speaker-test, mplayer, totem,...
	# I Ended up in using espeak.
	# Known bug: it works only if there is no other audio flux running
	if [ $TIME_LEFT -lt 6 ]
	then
		espeak "You have $TIME_LEFT minutes left."
		#espeak -v french "Il reste $TIME_LEFT minutes."
	fi

	# STEPs SEVEN and EIGHT
	# Find out if $VICTIM exhausted the allowed time limit.  If there's still
	# $TIME_LEFT, decrease by 1 and store the new value in the configuration file.
	# Otherwise lock the screen (or force an ungraceful logout).

	if [ $TIME_LEFT -gt 0 ]
	then
		# There is still time left:
		TIME_LEFT=`expr $TIME_LEFT - 1`
	 	echo $TIME_LEFT > $TIME_LEFT_FILE
     	echo $TIME_LEFT > $TIME_LEFT_FILE_FOR_USER
 	else
		# time expired, we lock screen or logout:

		#TPV:  Works with Xfce4, replace 'xfce4-session' with approppriate one to adapt for the others:
		# sudo -u $VICTIM DISPLAY=$DISP xfce4-session-logout --logout # Return a D-Bus error: "Failed to connect to socket"
		sudo -u $VICTIM DISPLAY=$DISP kill `ps -ef | grep xfce4-session | grep -v grep | grep ^$VICTIM | tr -s ' ' | cut -f 2 -d ' '`  
		# sudo -u $VICTIM DISPLAY=$DISP gnome-screensaver-command --activate --lock	  # If using gnome

		# The command below will force an ungraceful logout -- not recommended!
		# passwd -l $VICTIM
		# sudo pkill -u $VICTIM   #TPV: Not applicable if user has a server running under his name.
	fi

	# We're done for this victim!
done

# We're done for all victims!

# EOF
echo -----------------------------------------------------------

Re: Parental Control: Limiting computer usage time

Posted: Tue Mar 01, 2016 4:38 am
by ganamant
When I was a kid, computers were only used in banks and science labs, so I can't really relate, but if I watched to much TV, say, my parents would understand I was bored and give me something real to do, or suggest that I should call a buddy (on the land phone, of course) and hang out with him.

On the technical side, nobody mentioned that CD/USB booting should be disabled on the BIOS, too, lest a live distro be used to circumvent not only the script, but the very OS. Oh, and let's not forget regular and diligent backups. You never know what a pissed-off kid can do "by accident".

Re: Parental Control: Limiting computer usage time

Posted: Tue Mar 01, 2016 5:24 am
by LinuxJim
Great idea!

Someone has to play the devil's advocate here, so...

What's to prevent the user from typing one of:

Code: Select all

gnome-screensaver-command --inhibit

Code: Select all

gnome-screensaver-command --exit
...before the expiration time? (kids are extraordinarily crafty) ;)

Re: Parental Control: Limiting computer usage time

Posted: Tue Mar 01, 2016 5:27 am
by Pjotr
When my children were younger and still living in the parental house, I took another approach: I set a time limit *in the router* for their MAC addresses. Stock Linksys router firmware allows for that, and also third-party router firmware like Tomato RAF.

The internet would die on their computers at 20:00 hours, at which point they always re-joined us in the living room, to watch TV or to read. At 7:00 the internet would relive again, thus ensuring they would use the night for sleeping. Worked very nicely. :mrgreen:

Re: Parental Control: Limiting computer usage time

Posted: Tue Mar 01, 2016 6:21 am
by ganamant
Pjotr wrote:When my children were younger and still living in the parental house, I took another approach: I set a time limit *in the router* [...]
I was about to suggest something like that, too, but then I thought maybe I was making an assumption too many. But if, indeed

Code: Select all

computer_use == internet_use
then your solution is the most practical and robust one. I also think it keeps the piss-off factor lower, since the computer itself doesn't seem treacherous (just guessing on this one).

Every time I fail to realise that "computer" equals "the web" for most of today's kids*, I feel like an oldtimer. :mrgreen:

______________
*Not to mention many adults, but that's another story...

Re: Parental Control: Limiting computer usage time

Posted: Mon Aug 07, 2017 8:39 am
by Thomas Baeckeroot
Pjotr wrote:I set a time limit *in the router* for their MAC addresses.
That is a solution I recommend also, if needed. It works also for their mobile devices (tablet, phones, …). Down side of this is that when sharing a computer, all users would have the same restriction (including myself!).
Actual examples to illustrate:
- one computer used by the whole family, including parents
- one computer shared with 2 brothers
- etc…

("Pilosopong Tasyo" told about this upper here)

Re: Parental Control: Limiting computer usage time

Posted: Fri Sep 08, 2017 7:03 am
by Termy
What about making use of the SECONDS variable and using that to check for a limit, as set per a rules file (variables sourced, like a config file)? The script could run somewhere the kids can't get access to, like /etc/bash.bashrc or /etc/profile. Presumably the admin will have prevented them access to root via sudo and stuff. I would also use paths for those non-builtin commands.

Unfortunately, for as long as they have physical access to the machine, there are a whole host of ways to circumvent this. You'd have quite a task on your hands trying to lock it down, yet keeping it functional for them. I think it would take a lot more than just a script. For example, they could boot into single user mode and have immediate root access, after which they could change it all; this, like many things, would need to be disabled, but this comes at a cost. You could write scripts and what-not to check for attempts at circumventing it, but then that's even more work.

Probably easier to just yell at them to get off the machine :P

None-the-less, I find this an interesting concept, so I may write my own take on this functionality.

Oh, and reading down, I'm glad to see the timer setting in a router mentioned, as I was thinking I remember seeing that somewhere before. It's possible to change your system's MAC address, but I dunno if that works on-the-fly, or whether it's something the router would pick up, or whether it's something that can never truly be changed; it's not something I've really looked into.

Re: Parental Control: Limiting computer usage time

Posted: Fri Sep 08, 2017 7:42 am
by Pjotr
Termy wrote:It's possible to change your system's MAC address, but I dunno if that works on-the-fly, or whether it's something the router would pick up, or whether it's something that can never truly be changed; it's not something I've really looked into.
It can indeed be spoofed, but that requires more technical skills than my children used to have. :mrgreen:

Parental Control: Limiting computer usage time made easier…

Posted: Sun Sep 10, 2017 6:08 am
by Thomas Baeckeroot
Hi all,

I just made this available easily from my GitHub https://github.com/Thomas-Baeckeroot/Pa ... ontrol.git .

To download and install this, open a Terminal and run the commands below:

Code: Select all

cd /tmp/
git clone https://github.com/Thomas-Baeckeroot/ParentalControl.git
cd ParentalControl/
./install.sh
Administrator password will be requested during the installation process (to install the cron job, to copy the script, …). From there you will be guided for configuration. There is also an ./uninstall.sh at the same place just in case. It is build to work with all Ubuntu based distro (Mint, … probably all debian also). If any issue occurs please let me know, including system version and graphical environment in comments:

Code: Select all

uname -a
echo $XDG_CURRENT_DESKTOP

Re: Parental Control: Limiting computer usage time made easier…

Posted: Sun Sep 10, 2017 9:20 am
by Termy
Thomas Baeckeroot wrote:--snip--
Nice one. I'm just looking through your install.sh script now. On line 23, I see:

Code: Select all

sudo crontab -l | grep limit-usage-time.sh > nul
But I've never seen "> null" before, so I suspect it might be some sort of alias, perhaps a zsh alias, for /dev/null. This command would redirect the output from grep into a file called "nul" in the current directory; this would blast anything away which the user has in that directory which happened to be called nul.

I'd also suggest a small change, although it's unnecessary, it's a little simpler:

Code: Select all

if sudo crontab -l | grep limit-usage-time.sh &> /dev/null; then
	echo "Parental control script already in cron... Probably not the first time this install script is ran."
The reason is that the exit status can tested like that, rather than using the special parameter $?. Another small change you'll see above is that I used &> instead of >, to redirect both STDOUT and STDERR to /dev/null; that's how I'd do it, since I'm guessing you're not wanting output there, as you just want to test the exit status.

On line 19, you have:

Code: Select all

sudo cp limit-usage-time.sh /root/ || echo "An ERROR or WARNING occurred when copying script to root folder!"
I'd use something like "...copying script to '/root'!" to avoid ambiguity with the root of the directory structure, /.

I noticed on line 20 that you're changing the mode of the limit-usage-time.sh script to make it executable for the owner, but wouldn't the owner be root and therefore already have such powers? Especially as you're using sudo to copy the file over.

On line 24:

Code: Select all

if [ "$?" == "0" ]; then
You're using the == operator, but you're testing for a numeric value. Technically, it wouldn't make a difference here, but as a rule, I personally use numeric operators for numeric values and string operators on strings, unless there's a chance for either. My suggestion:

Code: Select all

if [ $? -eq 0 ]; then
This means if the parameters $? is equal to 0. I did away with the quotes, since it's not a string and I'm fairly sure $? won't store multiple fields. Doesn't really matter about the quotes, AFAIK.

For VICTIMS, on line 36, I had some fun with this, this should be more efficient:

Code: Select all

VICTIMS=`for I in `cut -d ":" -f 1,3 /etc/passwd`; { ! [ ${I/*:} -eq 65534 ] && [ ${I/*:} -ge 1000 ] && echo "${I%:*}"; }`
Works fine for me. This way, instead of using the bulkier awk, you can call only cut and do the rest with standard shell stuff. If it were me, I'd hook it up like this, to keep it readable:

Code: Select all

VICTIMS=$(
	for I in `cut -d ":" -f 1,3 /etc/passwd`
	{
		! [ ${I/*:} -eq 65534 ] && [ ${I/*:} -ge 1000 ] && echo "${I%:*}"
	}
)
I've added that to my repertoire because I see that being handy in the future! :)

For line 42, you have this:

Code: Select all

defaultadmin=`who am i | awk '{print $1}'`
Forgive me if I'm missing something here, but you can use the variable $USER, or the command whoami, to get the current user. Bringing awk into it (I would have otherwise recommended cut -f " " -f 1) is not something I would recommend here.

I used to use awk all the time, but learned how much quicker and more efficient using other tools can be. Plus, there's no guarantee awk will be on a system, but you're far more likely to find tools like cut and grep. For example, cut is part of the coreutils package which is quite the norm for a Linux distribution, especially Ubuntu/Debian systems.

For lines 44-47, you were getting the terminal file for the current terminal. This can be done much more efficiently with stat (coreutils) and nothing else, except of course tty (coreutils):

Code: Select all

stat --format="%U" `tty`
I've gotta dash, but if you'd like me to continue later, let me know. Loving what you have though. Bye for now.

Re: Parental Control: Limiting computer usage time

Posted: Sun Feb 04, 2018 6:22 pm
by Ferrari1978
So it's working on Cinnamon 18.3 ? If still no what do i need to do make it works?

Re: Parental Control: Limiting computer usage time

Posted: Mon Apr 09, 2018 9:53 pm
by Sugarcrisp
I didn't read through the script fully to see if it mentioned anything about "Guest Login". If not, you will need to address this also. :lol: