Skip to content

Instantly share code, notes, and snippets.

@knaka
Last active May 12, 2016 09:38
Show Gist options
  • Select an option

  • Save knaka/d44f4b4e301f13314080dbf63b5159aa to your computer and use it in GitHub Desktop.

Select an option

Save knaka/d44f4b4e301f13314080dbf63b5159aa to your computer and use it in GitHub Desktop.
Run processes while you do not touch your Mac.
#!/bin/bash
# -*- coding: utf-8 -*-
export PATH=/usr/local/bin:/usr/local/sbin/:/usr/bin/:/usr/sbin/:/bin/:/sbin/
## Avoid reentrance.
exec 9< $0
perl -mFcntl=:flock -e "open(LOCK,'<&=9');exit(!flock(LOCK,LOCK_EX|LOCK_NB))" || exit 0
## Exit for error or undefined.
set -eu
idlethresh=$((60 * 5))
checkinterval=10
# idlethresh=5
# checkinterval=5
## Do not start nor continue with these SSIDs.
badssids=("Too Slow", "Too Expensive")
## Do not start nor continue with these network services.
badnwsvcs=("Bluetooth PAN")
contains () {
local e
for e in "${@:2}"
do
test "$e" == "$1" && return 0
done
return 1
}
function badnetworkp() {
local ssid
local badnwsvc
ssid=$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | sed -n -e "s/^ *SSID: //p")
if test -n "$ssid" && contains "$ssid" "${badssids[@]}"
then
echo "Bad Wi-Fi is active."
return 0
fi
for badnwsvc in "${badnwsvcs[@]}"
do
if test -n "$(/usr/sbin/networksetup -getinfo "Bluetooth PAN" | sed -ne s/"^IP address: //p")"
then
echo "Bad network service is active."
return 0
fi
done
return 1
}
if badnetworkp
then
echo "Network connection is bad one. Exiting."
exit 0
fi
: ${FORCE:=""}
## Get UI idle time in second.
function idlesec() {
test -n "$FORCE" && echo 86400 && return
echo $(($(ioreg -c IOHIDSystem | grep HIDIdleTime | head -n 1 | sed 's/.* = //') / 1000000000))
}
## Stop for a while if UI is recently used.
echo Waiting.
while :
do
test "$(idlesec)" -ge "$idlethresh" && break
sleep $checkinterval
done
## Get child process IDs.
function children() {
for pid in $(pgrep -P $1)
do
echo $pid
children $pid
done
}
## Send signal to all child processes.
function killtree() {
kill -s $1 $pid $(children $2) && :
}
## Absolute path of this script.
self="$(p="$0";while :;do t="$(readlink "$p")";cd "$(dirname "$p")";test -z "$t"&&break||p="$t";done;echo "$(pwd -P)/$(basename "$p")")"
pid=
function onexit() {
trap "" SIGTERM # Ignore
kill -- -$$ && : # Not option but process group
## command line - What is a stopped process in linux? - Super User http://superuser.com/questions/403200/what-is-a-stopped-process-in-linux
kill -CONT -- -$$ && :
}
# function onexit() {
# test -n "$pid" && killtree TERM "$pid" || :
# }
trap onexit SIGINT SIGTERM EXIT
## Run all the executables under $self.d/ sequently.
for file in $self.d/*
do
base=$(basename "$file")
test "${base:0:1}" = "_" && continue
echo "$base" | grep -q -e "~" -e "#" && continue
$file &
pid=$!
while :
do
if badnetworkp
then
echo Network connection has been changed to bad one. Exiting.
killtree TERM $pid
wait
exit 0
fi
stat="$(ps auxww $pid | tail -n +2 | awk '{print $8}' | sed -e 's/\(.\).*/\1/')"
test -z "$stat" && pid="" && break
case $stat in
R | S | D ) # Running
if test "$(idlesec)" -lt "$idlethresh"
then
killtree STOP $pid
echo "Stopped subprocess(es)."
fi
;;
T ) # Stopped
if test "$(idlesec)" -ge "$idlethresh"
then
killtree CONT $pid
echo "Restarted subprocess(es)."
fi
;;
esac
sleep $checkinterval
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment