Last active
August 29, 2015 14:07
-
-
Save mschuerig/e6b245320c5cf56b60fd to your computer and use it in GitHub Desktop.
Server sleep scripts. Run in the evening as a cron job.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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