#!/bin/bash # shutdownasap version #VERSION# set -e . #ETCDIR#/shutdownasap.conf mkdir -p "${tmpDir}" cd "${tmpDir}" quiet=false intentionSet=false while [ $# -gt 0 ]; do case "$1" in '-a') echo 'none' >"${tmpDir}/intention" exit ;; '-q') quiet=true ;; '-r') echo 'reboot' >"${tmpDir}/intention" intentionSet=true ;; '-R') if [ -r "${tmpDir}/intention" ] \ && grep -qxF 'shutdown' "${tmpDir}/intention" \ && [ -r "${tmpDir}/pid" ] \ && kill -0 "$(cat "${tmpDir}/pid")"; then exit fi echo 'reboot' >"${tmpDir}/intention" intentionSet=true ;; *) >&2 echo 'usage: shutdownasap [-q] [-a|-r|-R]' exit 1 ;; esac shift done if ! ${intentionSet}; then echo 'shutdown' >"${tmpDir}/intention" fi [ -r "${tmpDir}/pid" ] && kill -0 "$(cat "${tmpDir}/pid")" && exit echo $$ > "${tmpDir}/pid" capture_output() { local exit_code local output output=$( "$@" 2>&1 ) \ || exit_code=$? if ! ${quiet}; then printf '%s\n' "${output}" fi return ${exit_code} } beforeWatchHook i=1 while [ ${i} -gt 0 ] || ! capture_output additionalWatchHookSlow do if [ ${i} -eq 0 ] then i=1 fi sleep 1 prozesse=$( ps aux \ | grep -v grep \ | grep -vF 'rsync --daemon --no-detach' ) nochwarten=false if [ -d "${waitForDir}" ] && ls -1A "${waitForDir}" | grep -q "." then nochwarten=true if ! ${quiet}; then echo ".warteauf: " ls -1A "${waitForDir}" fi fi if users | grep -q "." then nochwarten=true if ! ${quiet}; then echo -n "users: " users fi fi errors=$( find /sys/devices/virtual/block/ \ -name 'array_state' \ -exec grep -HvxF 'clean' {} + \ , \ -name 'sync_action' \ -exec grep -HxF 'recover' {} + \ , \ -name 'degraded' \ -exec grep -HvxF '0' {} + ) || true if [ -n "${errors}" ]; then nochWarten=true if ! ${quiet}; then printf 'unclean raid array(s):\n%s\n' "${errors}" fi fi for s in "${!shutDownNoGoProcesses[@]}" do if echo "${prozesse}" | grep -q "\(\s\|/\)${shutDownNoGoProcesses[${s}]}\(\$\|\s\)" then nochwarten=true if ! ${quiet}; then echo "prozess: ${s}" fi fi done for s in "${!shutDownNoGoFiles[@]}" do if [ -e "${shutDownNoGoFiles[${s}]}" ] && echo "${prozesse}" | grep -q "^\S\+\s\+$(cat "${shutDownNoGoFiles[${s}]}")\s" then nochwarten=true if ! ${quiet}; then echo "datei: ${s}" fi fi done if ! capture_output additionalWatchHookFast then nochwarten=true if ! ${quiet}; then echo "additionalWatchHookFast" fi fi if ${nochwarten} then if ! ${quiet}; then echo "warten ..." fi i=10 continue else if ! ${quiet}; then echo "noch ${i} Sekunden" fi fi i=$[${i}-1] done capture_output beforeShutDownHook if command -v sudo >/dev/null \ && [ "$(whoami)" != 'root' ]; then pre='sudo' else pre='' fi case "$(head -n1 "${tmpDir}/intention")" in 'reboot') ${pre} /sbin/reboot ;; 'shutdown') ${pre} /sbin/poweroff ;; 'none') echo 'shutdown was aborted' ;; *) printf 'intention "%s" not implemented\n' "$(head -n1 "${tmpDir}/intention")" exit 1 ;; esac cd / rm -rf --one-file-system "${tmpDir}"