3 ## Pings specified host and runs specified program if no responding
4 ## Copyright (c) 2005-2008 by Michal Nazarewicz (mina86/AT/mina86.com)
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 3 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, see <http://www.gnu.org/licenses/>.
19 ## This is part of Tiny Applications Collection
20 ## -> http://tinyapps.sourceforge.net/
24 ## I use it to shut down my PC when my brother shuts down his PC which
25 ## is a router. It may be also used to run a reconnect script when
26 ## connection is loast. It can be also used to monitor another PC and
27 ## send (let say) SMS when it goes down.
34 echo 'Check v0.2 (c) 2005,2006 by MichaĆ Nazarewicz'
44 usage: check.sh [ <options> ] [ [--] <action> [ <arg> ... ] ]
46 -h --help Displays help screen and exits
47 -H --long-help Displays long help screen and exits
48 -V --version Displays vesion and exits
49 -q --quiet Displays less messages
50 -r --retry=<count> Runs <action> after <count> failed checkings [10]
51 -i --interval=<int> Waits <int> seconds betwenn each checking [10]
52 -c --check=<check> Runs <check> to check [check_ping www.google.com]
53 -k --keep-going Restarts after running action [no]
54 -t --trap=<trpap> Executes <trap> when signal is trapped [exit 0]
55 -T --ignore-sig Ignores signals [no]
57 Single letter options may not be given as one argument (eg. -kTq).
59 <action> Program to be run when check faileds [exit]
60 <arg> ... Arguments to the <action> [1]
63 if [ "X$1" != "Xlong" ]; then return 0; fi
66 <check> must exit with 0 exit code if check succeeded or non-zero otherwise.
67 Script contains the fallowing built-in check functions:
68 check_ping <host> -- checks if <host> answers to ping
69 check_proc_load <proc> <load> -- checks if <proc>'s CPU load is below <load>
70 (<load> must be an integer betwen 1 and 100)
71 check_proc <proc> -- checks if <proc> is running
72 Each built-in function has also an alias with the first c letter removed.
74 The script exports variables CHECK_QUIET (empty if false, y if true),
75 CHECK_INGORESIG (empty if false, y if true), (in case of <action>)
76 CHECK_EXIT_CODE (exit code of <check>) and CHECK_TMP (path to a temporary
77 file) which both <check> and <action> should take into account.
81 ./check.sh '-check_proc_load X 95' -k -- killall X -q &
82 Kills X each time it uses more then 95% of CPU for 5 minutes. Usefull
83 when executed from system start scripts since it keeps running silently in
86 ./check.sh || /sbin/halt
87 Halts computer if www.google.com stops responding to pings (most likely
88 connection was lsot). May be canceled with Ctrl+C.
90 ./check.sh '-check_proc foo' -k -q -r100 -i1 -- /path/to/foo' &
91 Checks whether foo is runing and if not executes it. Useful when executed
92 from system start scripts since it keeps running silently in the
109 export CHECK_QUIET CHECK_IGNORESIG
111 CMD
="check_ping www.google.com"
117 while [ $# -ne 0 ]; do
119 -h|
--help) version
; usage
; exit 0; ;;
120 -H|
--long-help) version
; usage long
; exit 0; ;;
121 -V|
--version) version
; exit 0; ;;
123 -q|
--quiet) CHECK_QUIET
=yes ; ;;
124 -k|
--keep-going) KEEPGOING
=yes ; ;;
125 -T|
--ignore-sig) CHECK_IGNORESIG
=y
; ;;
127 -r|
--retry) RETRY
=$2 ; shift; ;;
128 -i|
--interval) SLEEP
=$2 ; shift; ;;
129 -c|
--count) CMD
=$2 ; shift; ;;
130 -t|
--trap) TRAPCMD
=$2; shift; ;;
132 -r*) RETRY
=${1#-?} ; ;; (--retry=*) RETRY
=${1#-*=} ; ;;
133 -i*) SLEEP
=${1#-?} ; ;; (--interval=*) SLEEP
=${1#-*=} ; ;;
134 -c*) CMD
=${1#-?} ; ;; (--check=*) CMD
=${1#-*=} ; ;;
135 -t*) TRAPCMD
=${1#-?}; ;; (--trap=*) TRAPCMD
=${1#-*=}; ;;
138 -*) echo Unknown option
: "$1"; exit 1; ;;
143 [ $# -eq 0 ] && set -- exit 1
146 [ -n "$CHECK_QUIET" ] || version
152 if [ "$RETRY" -lt 1 ]; then
153 echo '<count> must be integer >= 1'
156 if [ "$SLEEP" -lt 1 ]; then
157 echo '<interval> must be integer >= 1'
166 ping -c 1 "$1" 2>/dev
/null
>"$CHECK_TMP" ||
return 1
167 [ -n "$CHECK_QUIET" ] ||
head -n 2 "$CHECK_TMP" |
tail -n 1
170 heck_ping
() { check_ping
"$@"; }
173 LOAD
="$(ps -o %cpu -C "$1" |tail -n+2)"
174 if [ ! "$LOAD" ]; then
175 [ -n "$CHECK_QUIET" ] ||
printf '%s: not running\n' "$1"
178 [ -n "$CHECK_QUIET" ] ||
printf '%s: CPU Load %5s%%\n' "$1" "$LOAD"
180 [ "${LOAD%%.*}" -lt "$2" ]
182 heck_proc_load
() { check_proc_load
"$@"; }
185 if [ -z "$__CHECK_PROC_PKILL_PRESENT" ]; then
186 which pkill
>/dev
/null
2>&1
187 __CHECK_PROC_PKILL_PRESENT
=$?
190 if [ $__CHECK_PROC_PKILL_PRESENT -eq 0 ]; then
191 if ! pkill
-0 "^$1\$"; then return 1; fi
192 elif ! ps
-C "$1" >/dev
/null
2>/dev
/null
; then
196 if [ -n "$CHECK_QUIET" ]; then return 0; fi
197 case "$__CHECK_PROC_GLOBAL_VAR" in
198 (1) printf '%s: running (/)\r' "$1"; __CHECK_PROC_GLOBAL_VAR
=2; ;;
199 (2) printf '%s: running (-)\r' "$1"; __CHECK_PROC_GLOBAL_VAR
=3; ;;
200 (3) printf '%s: running (\\)\r' "$1"; __CHECK_PROC_GLOBAL_VAR
=0; ;;
201 (*) printf '%s: running (|)\r' "$1"; __CHECK_PROC_GLOBAL_VAR
=1; ;;
205 heck_proc
() { check_proc
"$@"; }
214 for N
in "$TMPDIR" "$TMP" "$TEMP" ~
/tmp
/tmp
; do
215 if [ -n "$N" ] && [ -d "$N" ] && [ -w "$N" ]; then
222 if which mktemp
>/dev
/null
2>&1; then
223 export CHECK_TMP
=$
(mktemp
"$CHECK_TMP/check-XXXXXXXX")
224 elif which tempfile
>/dev
/null
2>&1; then
225 export CHECK_TMP
=$
(tempfile
-d "$CHECK_TMP" -p "check-")
227 echo unable to create temporary
file, mktemp or tempfile required
>&2
231 trap '[ -f "$CHECK_TMP" ] && rm -f -- "$CHECK_TMP"' 0
238 if [ -n "$CHECK_IGNORESIG" ] ||
[ "X$1" = XUSR1
] ||
239 [ "X$1" = XUSR2
] ||
[ "X$1" = XALRM
]; then
240 [ -n "$CHECK_QUIET" ] ||
echo "Got SIG$1; ignoring..."
244 [ -n "$CHECK_QUIET" ] ||
echo "Got SIG$1"
248 for e
in HUP INT QUIT ABRT SEGV PIPE ALRM TERM USR1 USR2
; do
249 # shellcheck disable=SC2064
250 trap "catch_sig $e" "$e"
268 export CHECK_EXIT_CODE
=$?
269 count
=$
(( count
+ 1 ))
270 [ -n "$CHECK_QUIET" ] ||
printf " !!! %3d / %3d\r" "$count" "$RETRY"
273 if [ "$count" -ge "$RETRY" ]; then
274 [ -n "$CHECK_QUIET" ] ||
echo ' !!! Checking failed.'
275 [ -f "$CHECK_TMP" ] && rm -f -- "$CHECK_TMP"
277 [ -n "$KEEPGOING" ] ||
exit 0;