#!/bin/bash # shutdownasap version #VERSION# set -e . #ETCDIR#/shutdownasap.conf mkdir -p "${tmpDir}" cd "${tmpDir}" if [ $# -eq 1 ] && [ "x$1" = 'x-g' ]; then [ -r "${tmpDir}/pid" ] \ && [ -d "/proc/$(cat "${tmpDir}/pid")" ] \ && cat "${tmpDir}/intention" \ || echo 'none' exit fi 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" ] \ && [ -d "/proc/$(cat "${tmpDir}/pid")" ]; then exit fi echo 'reboot' >"${tmpDir}/intention" intentionSet=true ;; *) >&2 echo 'usage: shutdownasap [-q] [-a|-r|-R]' >&2 echo ' -a abort' >&2 echo ' -g get intention' >&2 echo ' -q quiet' >&2 echo ' -r reboot' >&2 echo ' -R reboot if not yet shutdown' exit 1 ;; esac shift done if ! ${intentionSet}; then echo 'shutdown' >"${tmpDir}/intention" fi [ -r "${tmpDir}/pid" ] \ && [ -d "/proc/$(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 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=$( [ -d /sys/devices/virtual/block/ ] \ && find /sys/devices/virtual/block/ \ -name 'array_state' \ -exec grep -HvxF "$(printf '%s\n' 'clean' 'active')" {} + \ , \ -name 'sync_action' \ -exec grep -HxF "$(printf '%s\n' 'recover' 'reshape')" {} + \ , \ -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 pgrep -af "(\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}]}" ] && [ -d "/proc/$(cat "${shutDownNoGoFiles[${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}"