Skip to content

Instantly share code, notes, and snippets.

@mschuerig
Last active August 29, 2015 14:07
Show Gist options
  • Save mschuerig/e6b245320c5cf56b60fd to your computer and use it in GitHub Desktop.
Save mschuerig/e6b245320c5cf56b60fd to your computer and use it in GitHub Desktop.
Server sleep scripts. Run in the evening as a cron job.
#! /bin/bash
#
# Save as /usr/local/sbin/try-to-sleep
#
# Have cron try it regularly.
# /etc/cron.d/try-to-sleep:
# 12,27,42,57 22-23,0-5 * * * root /usr/local/sbin/try-to-sleep
#
set -o errexit
set -o noclobber
set -o nounset
set -o pipefail
STAY_AWAKE="/var/local/stay-awake"
IGNORED_CRONJOBS='^(/usr/sbin/cron|/usr/sbin/incrond|/usr/bin/atop|.* /usr/local/sbin/try-to-sleep)'
RECENT_MINUTES=15
_may_sleep=1
_log=''
_dry_run=''
_verbose=''
_debug=''
usage() {
echo "Usage: $0 [ --dry-run | -n ] [ --verbose | -v ] [ --debug | -d ]"
}
while (( $# > 0 )); do
case "$1" in
--dry-run|-n)
shift
_dry_run=1
;;
--verbose|-v)
shift
_verbose=1
;;
--debug|-d)
shift
_debug=1
;;
--help|-h)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
done
doit=''
if [[ $_dry_run = 1 ]]; then
doit=echo
fi
can_sleep() {
[[ $_may_sleep = 1 ]]
}
dont_sleep() {
_may_sleep=0
}
continue_checks() {
[[ $_may_sleep = 1 ]] || [[ $_verbose = 1 ]]
}
active_connections() {
netstat -tn | fgrep 'ESTABLISHED' || [[ $? = 1 ]]
}
running_cronjobs() {
local pids
pids=$( cat /sys/fs/cgroup/systemd/system.slice/*cron.service/cgroup.procs )
if [[ -n $pids ]]; then
ps -ho command -p $pids \
| grep -Eiv "$IGNORED_CRONJOBS" || [[ $? = 1 ]]
fi
}
no_rest_for_the_wicked() {
test -f "$STAY_AWAKE"
}
log() {
if [[ $_verbose = 1 ]]; then
_log="${_log}${*}\n"
fi
}
debug() {
if [[ $_debug = 1 ]]; then
echo "$*"
fi
}
dont_sleep_if() {
if continue_checks; then
debug "dont_sleep_if $1"
if $1; then
debug "-> DON'T"
log "$2"
dont_sleep
else
debug "-> MAY"
fi
fi
}
dont_sleep_if_any() {
if continue_checks; then
debug "dont_sleep_if_any $1"
local out
out=$( $1 )
debug "$out"
if [[ -n $out ]]; then
debug "-> DON'T"
log "$2"
dont_sleep
else
debug "-> MAY"
fi
fi
}
dont_sleep_if_running() {
if continue_checks; then
debug "dont_sleep_if_running $1"
local p msg
p="$1"
if pidof "$p" > /dev/null ; then
debug "-> DON'T"
msg=${2:-"Process is running: $p"}
log "$msg"
dont_sleep
else
debug "-> MAY"
fi
fi
}
dont_sleep_if_recent() {
if continue_checks; then
debug "dont_sleep_if_recent $1"
local file now age msg
file="$1"
now=$( date +'%s' )
age=$( stat -c '%Y' "$file" )
if (( (now - age) <= ($RECENT_MINUTES * 60) )); then
debug "-> DON'T"
msg=${2:-"Recently modified: $file"}
log "$msg"
dont_sleep
else
debug "-> MAY"
fi
fi
}
dont_sleep_if no_rest_for_the_wicked "Staying awake as requested"
dont_sleep_if_any running_cronjobs "Cron jobs are running"
dont_sleep_if_any active_connections "Connections are open"
dont_sleep_if_running sftp-server
dont_sleep_if_running btrfs
dont_sleep_if_running btrfsck
dont_sleep_if_running fstrim
dont_sleep_if_running rsync
dont_sleep_if_running snapperd
dont_sleep_if_running tmux
dont_sleep_if_recent /var/lib/mpd/state
echo -en "$_log"
if can_sleep; then
$doit systemctl hybrid-sleep
elif [[ $_verbose = 1 ]]; then
echo "Can't go to sleep yet."
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment