lightsout for linux (suspend when no network activity for 1 hour)
#!/bin/bash | |
######################################################################## | |
# LIGHTS OUT FOR LINUX (lofl) # | |
# This script suspends the computer if it's idle for a given period of # | |
# time. It monitors network activity, logged on users and CPU load. # | |
######################################################################## | |
# maximum packet count per minute – usually not more than 12-15 | |
net_threshold=12 | |
# maximum CPU load | |
load_threshold=0.4 | |
# maximum IDLE time in minutes | |
time_threshold=60 | |
# network interface to watch | |
interface=eno1 | |
### DO NOT CHANGE ANYTHING BELOW THIS LINE ############################# | |
# TODO: calculate $net_threshold if not set | |
# store user count and load in variables | |
system_up=$(uptime) | |
system_users=$(echo "$system_up" | perl -ne "print for /([0-9]+)\suser/") | |
system_load=$(echo "$system_up" | perl -ne "print for /([0-9]+\,[0-9]{2})$/" | sed "s/,/./") | |
# tell the user | |
printf "Logged in users:\t$system_users\n" | |
printf "Load avg (15min):\t$system_load (max $load_threshold)\n" | |
# create a temporary file to store the network packet count across calls | |
countfile="/tmp/lightsout_${interface}_count" | |
printf "Interface:\t\t$interface\n" | |
if [[ -f $countfile ]] | |
then | |
changed=$(date -r $countfile +%s) | |
printf "Last record:\t\t$(date -d @"$changed")\n" | |
else | |
printf "0" > $countfile | |
fi | |
# see how many network packets were sent over the given interface | |
packet_sent=$(cat /sys/class/net/$interface/statistics/tx_packets) | |
# calculate the difference to the last call of the script | |
let "packet_difference=$packet_sent-$(cat $countfile)" | |
let "net_threshold *= $time_threshold" | |
# tell the user how many packets were sent | |
printf "Network packets sent:\t$packet_sent (diff: $packet_difference/$net_threshold)\n" | |
# check if the packet count exceeds the threshold set by the user | |
if (( "$packet_difference" > "$net_threshold" )); | |
then | |
printf "resetting packet count...\n" | |
printf "$packet_sent" > $countfile | |
else | |
let "datediff = $(date +%s) - $changed" | |
let "time_threshold *= 60" | |
# tell the user the assumed IDLE time | |
printf "IDLE seconds:\t\t$datediff/$time_threshold\n" | |
if (( "$datediff" > "$time_threshold" )); | |
then | |
# are users still logged in? | |
if (( "$system_users" > "0" )); | |
then | |
printf "not suspending because users are logged in.\n"; | |
else | |
# is the CPU occupied? | |
if [[ $(echo "$system_load>$load_threshold" | bc) -eq 1 ]]; | |
then | |
printf "not suspending due to CPU load.\n"; | |
else | |
# reset packet counter and suspend | |
printf 0 > $countfile | |
printf "suspending...\n" | |
systemctl suspend | |
fi | |
fi | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
@n1trux -
Your system load parsing does not work on my Centos 7
(my uptime output looks as follows)
19:58:11 up 2:49, 7 users, load average: 0.49, 0.48, 0.55
Here is the code I used which should be more portable across distributions:
system_load=$(cut -d ' ' -f 3 </proc/loadavg)
And for system_users you can simplify to:
system_users=$(w -h | wc -l)