Loading checkservices +190 −150 Original line number Diff line number Diff line Loading @@ -19,62 +19,43 @@ # Check running systemd services for binary update # Convenient way to restart updated systemd service after upgrade # bash options shopt -s xpg_echo # disable grep options to avoid non default behaviour unset GREP_OPTIONS # Systemd cgroup path # systemd cgroup path SYSTEMD_CGROUP_BASE_PATH='/sys/fs/cgroup/systemd' # colors if [[ -t 1 ]]; then shopt -s xpg_echo c_arrow='\e[1;34m' c_title='\e[1;37m' c_svc='\e[1;35m' c_warn='\e[5;30;43m' c_error='\e[1;31m' c_rst='\e[m' C_BOLD='\e[1m' C_BLUE='\e[34m' C_RED='\e[31m' C_WHITE='\e[37m' C_RESET='\e[m' fi # default options autoconfirm=0 # autoconfirmation dbus=1 # relauch when dbus debug=0 # debug mode failed=1 # display failed service at the end pacdiff=1 # run pacdiff reload=1 # reload systemd restart=1 # restart services serialize=0 # run in parallel status=1 # display status after systemctl user_slice=0 # act on users services # display application usage and exit 2 usage() { echo "usage ${0##*/} [options]" echo "description: check for updated files in a service" echo 'options:' echo ' -h: this help' >&2 echo " -d: debug mode" >&2 echo " -c: auto confirmation" >&2 echo " -b/-B: restart (or not) ${0##*/} if dbus was updated (default: $dbus)" >&2 echo " -l/-L: call (or not) systemd daemon-reload (default: $reload)" >&2 echo " -f/-F: display (or not) failed services before quit (default: $failed)" >&2 echo " -p/-P: call (or not) pacdiff before act (default: $pacdiff)" >&2 echo " -r/-R: restart (or not) services with updated files (default: $restart)" >&2 echo " -s/-S: display (or not) status of restarted service (default: $status)" >&2 echo " -u/-U: act (or not) on services in users slice (default: $user_slice)" >&2 echo " -z/-Z: serialize (or not) action (default: $serialize)" >&2 exit 2 } AUTOCONFIRM=0 # autoconfirmation DBUS=1 # relauch when dbus FAILED=1 # display failed service at the end PACDIFF=1 # run pacdiff RELOAD=1 # reload systemd RESTART=1 # restart services SERIALIZE=0 # run in parallel STATUS=1 # display status after systemctl USER_SLICE=0 # act on users services # print $* as an arrow line arrow() { printf "%b==> %b%s%b\n" "$c_arrow" "$c_title" "$*" "$c_rst" printf "${C_BOLD}${C_BLUE}:: ${C_WHITE}%s${C_RESET}\n" "$*" } # print $* as an error message error() { printf "%bError: %b%s%b\n" "$c_error" "$c_title" "$*" "$c_rst" >&2 printf "${C_BOLD}${C_RED}Error:: ${C_WHITE}%s${C_RESET}\n" "$*" >&2 } # usage : in_array( $needle, $haystack ) Loading @@ -92,7 +73,7 @@ in_array() { # ask for confirmation # return 0 when confirmed, otherwise 1 confirm() { (( $autoconfirm == 1 )) && return 0 (( $AUTOCONFIRM == 1 )) && return 0 local -i try local ans for try in 5 4 3 2 1; do Loading @@ -107,118 +88,96 @@ confirm() { return 1 } while getopts 'ahBbdFfLlPpRrSsUuZz' opt; do case $opt in a) autoconfirm=0;; B) dbus=0;; b) dbus=1;; d) debug=1;; F) failed=0;; f) failed=1;; L) reload=0;; l) reload=1;; P) pacdiff=0;; p) pacdiff=1;; R) restart=0;; r) restart=1;; S) status=0;; s) status=1;; U) user_slice=0;; u) user_slice=1;; Z) serialize=0;; z) serialize=1;; *) usage;; esac done shift $((OPTIND - 1)); (( $# > 0 )) && usage # avoid to be sighup'ed by interactive shell trap '' SIGHUP # from now, we need to be root (( $UID != 0 )) && error 'You need to be root' && exit 1 # get running systemd services get_services() { systemctl --no-legend --full --type service --state running|cut -f1 -d' ' } # call pacdiff (( $pacdiff )) && arrow 'Run pacdiff' && pacdiff # reload units list (( $reload )) && arrow 'Reload systemd' && systemctl --system daemon-reload # list of running services arrow 'List runnings systemd services' declare -a services services=($(systemctl --no-legend --full --type service --state running|cut -f1 -d' ')) # list of bus names arrow 'List Dbus clients' declare -a buses buses=($(dbus-send --system --dest=org.freedesktop.DBus --type=method_call \--print-reply \ /org/freedesktop/DBus org.freedesktop.DBus.ListNames|sed -rn 's/\s*string "(.*)"/\1/p')) # count beggar services arrow "Search for updated mapped files" declare -a needy=() pids=() declare -i pid=0 for svc in "${services[@]}"; do unit_path="$(systemctl -p ControlGroup show "$svc"|cut -f 2 -d=)" busname="$(systemctl -p BusName show "$svc"|cut -f 2 -d=)" # get systemd services with updated mapped files get_broken_maps() { local service path pidfile unit_path maps_path pids deleted local -a pids=() local -i pid=0 for service in $(get_services); do unit_path="$(systemctl -p ControlGroup show "$service"|cut -f 2 -d=)" # get the right pidfile name unset pidfile pidfile='' for path in "$SYSTEMD_CGROUP_BASE_PATH$unit_path/cgroup.procs" \ "$SYSTEMD_CGROUP_BASE_PATH$unit_path/tasks"; do [[ -r "$path" ]] && pidfile="$path" && continue done [[ -z "$pidfile" ]] && error "Unable to find pid file for $svc." && continue [[ -z "$pidfile" ]] && error "Unable to find pid file for $service." && continue # skip non system units (( $user_slice == 0 )) && [[ "$unit_path" =~ /user\.slice/ ]] && continue (( $USER_SLICE == 0 )) && [[ "$unit_path" =~ /user\.slice/ ]] && continue # parse pidfile pids=( $(< "$pidfile") ) if (( "${#pids[*]}" == 0 )); then error "Unable to parse pid file for $svc." error "Unable to parse pid file for $service." continue fi for pid in "${pids[@]}"; do maps_path="/proc/$pid/maps" [[ -r "$maps_path" ]] || { error "Unable to read maps file of $svc for pid $pid." error "Unable to read maps file of $service for pid $pid." continue } deleted=$(grep -F '(deleted)' "$maps_path" |sed -nr 's|^\S+ ..x. \S+ \S+ \S+ \s+||p'|sort|uniq) if [[ -n $deleted ]] || { [[ -n "$busname" ]] && ! in_array "$busname" "${buses[@]}"; }; then needy+=("$svc") if (( $debug )); then echo "${c_title}Service:${c_svc} $svc${c_rst}" echo "${c_title}Pid:${c_rst} $pid" echo "${c_title}Bus:${c_rst} $busname" echo -n "${c_title}BusName matching on the system bus: ${c_rst}" in_array "$busname" "${buses[@]}" && echo 'Yes' || echo 'No' echo "${c_title}Deleted files:${c_rst}" echo "$deleted" echo fi # only file mapped as executable deleted="$(grep -F '(deleted)' "$maps_path"|sed -nr 's|^\S+ ..x. \S+ \S+ \S+ \s+||p')" if [[ $deleted ]]; then printf "%s\n" $service break fi done done } # get dbus clients on the system bus get_dbus_names() { dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply \ /org/freedesktop/DBus org.freedesktop.DBus.ListNames|sed -rn 's/\s*string "(.*)"/\1/p' } # display what we will do (( "${#needy[*]}" )) && echo '-------8<-------------------------------8<---------' for svc in "${needy[@]}"; do echo "systemctl restart '$svc'" # get systemd services not registered on dbus system bus get_missing_dbus() { local service busname local -a registered=($(get_dbus_names)) for service in $(get_services); do # get the service registered bus name busname="$(systemctl -p BusName show "$service"|cut -f 2 -d=)" if [[ "$busname" ]] && ! in_array "$busname" "${registered[@]}"; then echo $service fi done (( "${#needy[*]}" )) && echo '-------8<-------------------------------8<---------' } # start the dangerous action below if (( $restart == 1 && ${#needy[*]} > 0 )) && confirm 'Confirm service restart?'; then # display restart intruction from service name display_restart() { local service echo '-------8<-------------------------------8<---------' for service; do echo "systemctl restart '$service'" done echo '-------8<-------------------------------8<---------' } declare -A registered_pids=() declare -a running_pids=() declare -i last_registered_pids_count # restart systemd services given in arguments restart_services() { local service local -i last_registered_pids_count local -A registered_pids=() local -a running_pids=() # do the job, restart updated services for svc in "${needy[@]}"; do echo "Restarting ${c_svc}$svc${c_rst}" systemctl restart "$svc" & if (( $serialize )); then for service; do echo "systemctl restart $service" systemctl restart "$service" & if (( $SERIALIZE )); then wait # display status directly when serialize and not quiet (( $status )) && systemctl --no-pager --lines=0 status "$svc" (( $STATUS )) && systemctl --no-pager --lines=0 status "$service" else # register pids registered_pids[$!]="$svc" registered_pids[$!]="$service" fi done Loading @@ -235,7 +194,7 @@ if (( $restart == 1 && ${#needy[*]} > 0 )) && confirm 'Confirm service restart?' for pid in "${!registered_pids[@]}"; do in_array "$pid" "${running_pids[@]}" && continue # show units status (( $status )) && systemctl --no-pager --lines=0 status "${registered_pids[$pid]}" (( $STATUS )) && systemctl --no-pager --lines=0 status "${registered_pids[$pid]}" unset registered_pids[$pid] break done Loading @@ -249,18 +208,99 @@ if (( $restart == 1 && ${#needy[*]} > 0 )) && confirm 'Confirm service restart?' break fi done } # display application usage and exit 2 usage() { echo "usage ${0##*/} [options]" echo "description: check for updated files in a service" echo 'options:' echo ' -h: this help' >&2 echo " -c: auto confirmation" >&2 echo " -l/-L: call (or not) systemd daemon-reload (default: $RELOAD)" >&2 echo " -f/-F: display (or not) failed services before quit (default: $FAILED)" >&2 echo " -p/-P: call (or not) pacdiff before act (default: $PACDIFF)" >&2 echo " -r/-R: restart (or not) services with updated files (default: $RESTART)" >&2 echo " -s/-S: display (or not) status of restarted service (default: $STATUS)" >&2 echo " -u/-U: act (or not) on services in users slice (default: $USER_SLICE)" >&2 echo " -z/-Z: serialize (or not) action (default: $SERIALIZE)" >&2 exit 2 } # parse command line arguments # set options as global vars argparse() { local opt while getopts 'ahFfLlPpRrSsUuZz' opt; do case $opt in a) AUTOCONFIRM=0;; F) FAILED=0;; f) FAILED=1;; L) RELOAD=0;; l) RELOAD=1;; P) PACDIFF=0;; p) PACDIFF=1;; R) RESTART=0;; r) RESTART=1;; S) STATUS=0;; s) STATUS=1;; U) USER_SLICE=0;; u) USER_SLICE=1;; Z) SERIALIZE=0;; z) SERIALIZE=1;; *) usage;; esac done shift $((OPTIND - 1)); (( $# > 0 )) && usage } # warn if dbus was restart if in_array dbus.service "${needy[@]}"; then echo "${c_warn}After dbus restart, you should run ${0##*/} twice${c_rst}" >&2 if (( $dbus )) && [[ -z "$CHECKSERVICE_WAS_RESTARTED" ]]; then echo "${c_warn}Doing it for you. No need to thanks me!${c_rst}" >&2 export CHECKSERVICE_WAS_RESTARTED=1 exec "$0" "$@" # emulated program entry point main() { # avoid to be sighup'ed by interactive shell trap '' SIGHUP # from now, we need to be root (( $UID != 0 )) && error 'You need to be root' && exit 1 # parse command line options argparse "$@" # call pacdiff to ensure config files are updated before restart if (( $PACDIFF )); then arrow 'Run pacdiff' pacdiff fi # ensure systemd has been reloaded if (( $RELOAD )); then arrow 'Reload systemd' systemctl --system daemon-reload fi arrow 'Services with broken maps files' local -a broken_services=($(get_broken_maps)) echo "Found: ${#broken_services[@]}" if (( ${#broken_services[@]} )); then display_restart "${broken_services[@]}" if confirm 'Execute?'; then arrow 'Restart broken services' restart_services "${broken_services[@]}" fi fi arrow 'Services missing on the system bus' local -a missing_services=($(get_missing_dbus)) echo "Found: ${#missing_services[@]}" if (( ${#missing_services[@]} )); then display_restart "${missing_services[@]}" if confirm 'Execute?'; then arrow 'Restart missing services' restart_services "${missing_services[@]}" fi fi # list only failed systemd units if (( $FAILED )); then arrow "List failed units" systemctl --failed --all --no-pager --no-legend --full list-units fi } (( $failed )) && arrow "List failed units" && systemctl --failed --all --no-pager --no-legend --full list-units main "$@" exit 0 Loading
checkservices +190 −150 Original line number Diff line number Diff line Loading @@ -19,62 +19,43 @@ # Check running systemd services for binary update # Convenient way to restart updated systemd service after upgrade # bash options shopt -s xpg_echo # disable grep options to avoid non default behaviour unset GREP_OPTIONS # Systemd cgroup path # systemd cgroup path SYSTEMD_CGROUP_BASE_PATH='/sys/fs/cgroup/systemd' # colors if [[ -t 1 ]]; then shopt -s xpg_echo c_arrow='\e[1;34m' c_title='\e[1;37m' c_svc='\e[1;35m' c_warn='\e[5;30;43m' c_error='\e[1;31m' c_rst='\e[m' C_BOLD='\e[1m' C_BLUE='\e[34m' C_RED='\e[31m' C_WHITE='\e[37m' C_RESET='\e[m' fi # default options autoconfirm=0 # autoconfirmation dbus=1 # relauch when dbus debug=0 # debug mode failed=1 # display failed service at the end pacdiff=1 # run pacdiff reload=1 # reload systemd restart=1 # restart services serialize=0 # run in parallel status=1 # display status after systemctl user_slice=0 # act on users services # display application usage and exit 2 usage() { echo "usage ${0##*/} [options]" echo "description: check for updated files in a service" echo 'options:' echo ' -h: this help' >&2 echo " -d: debug mode" >&2 echo " -c: auto confirmation" >&2 echo " -b/-B: restart (or not) ${0##*/} if dbus was updated (default: $dbus)" >&2 echo " -l/-L: call (or not) systemd daemon-reload (default: $reload)" >&2 echo " -f/-F: display (or not) failed services before quit (default: $failed)" >&2 echo " -p/-P: call (or not) pacdiff before act (default: $pacdiff)" >&2 echo " -r/-R: restart (or not) services with updated files (default: $restart)" >&2 echo " -s/-S: display (or not) status of restarted service (default: $status)" >&2 echo " -u/-U: act (or not) on services in users slice (default: $user_slice)" >&2 echo " -z/-Z: serialize (or not) action (default: $serialize)" >&2 exit 2 } AUTOCONFIRM=0 # autoconfirmation DBUS=1 # relauch when dbus FAILED=1 # display failed service at the end PACDIFF=1 # run pacdiff RELOAD=1 # reload systemd RESTART=1 # restart services SERIALIZE=0 # run in parallel STATUS=1 # display status after systemctl USER_SLICE=0 # act on users services # print $* as an arrow line arrow() { printf "%b==> %b%s%b\n" "$c_arrow" "$c_title" "$*" "$c_rst" printf "${C_BOLD}${C_BLUE}:: ${C_WHITE}%s${C_RESET}\n" "$*" } # print $* as an error message error() { printf "%bError: %b%s%b\n" "$c_error" "$c_title" "$*" "$c_rst" >&2 printf "${C_BOLD}${C_RED}Error:: ${C_WHITE}%s${C_RESET}\n" "$*" >&2 } # usage : in_array( $needle, $haystack ) Loading @@ -92,7 +73,7 @@ in_array() { # ask for confirmation # return 0 when confirmed, otherwise 1 confirm() { (( $autoconfirm == 1 )) && return 0 (( $AUTOCONFIRM == 1 )) && return 0 local -i try local ans for try in 5 4 3 2 1; do Loading @@ -107,118 +88,96 @@ confirm() { return 1 } while getopts 'ahBbdFfLlPpRrSsUuZz' opt; do case $opt in a) autoconfirm=0;; B) dbus=0;; b) dbus=1;; d) debug=1;; F) failed=0;; f) failed=1;; L) reload=0;; l) reload=1;; P) pacdiff=0;; p) pacdiff=1;; R) restart=0;; r) restart=1;; S) status=0;; s) status=1;; U) user_slice=0;; u) user_slice=1;; Z) serialize=0;; z) serialize=1;; *) usage;; esac done shift $((OPTIND - 1)); (( $# > 0 )) && usage # avoid to be sighup'ed by interactive shell trap '' SIGHUP # from now, we need to be root (( $UID != 0 )) && error 'You need to be root' && exit 1 # get running systemd services get_services() { systemctl --no-legend --full --type service --state running|cut -f1 -d' ' } # call pacdiff (( $pacdiff )) && arrow 'Run pacdiff' && pacdiff # reload units list (( $reload )) && arrow 'Reload systemd' && systemctl --system daemon-reload # list of running services arrow 'List runnings systemd services' declare -a services services=($(systemctl --no-legend --full --type service --state running|cut -f1 -d' ')) # list of bus names arrow 'List Dbus clients' declare -a buses buses=($(dbus-send --system --dest=org.freedesktop.DBus --type=method_call \--print-reply \ /org/freedesktop/DBus org.freedesktop.DBus.ListNames|sed -rn 's/\s*string "(.*)"/\1/p')) # count beggar services arrow "Search for updated mapped files" declare -a needy=() pids=() declare -i pid=0 for svc in "${services[@]}"; do unit_path="$(systemctl -p ControlGroup show "$svc"|cut -f 2 -d=)" busname="$(systemctl -p BusName show "$svc"|cut -f 2 -d=)" # get systemd services with updated mapped files get_broken_maps() { local service path pidfile unit_path maps_path pids deleted local -a pids=() local -i pid=0 for service in $(get_services); do unit_path="$(systemctl -p ControlGroup show "$service"|cut -f 2 -d=)" # get the right pidfile name unset pidfile pidfile='' for path in "$SYSTEMD_CGROUP_BASE_PATH$unit_path/cgroup.procs" \ "$SYSTEMD_CGROUP_BASE_PATH$unit_path/tasks"; do [[ -r "$path" ]] && pidfile="$path" && continue done [[ -z "$pidfile" ]] && error "Unable to find pid file for $svc." && continue [[ -z "$pidfile" ]] && error "Unable to find pid file for $service." && continue # skip non system units (( $user_slice == 0 )) && [[ "$unit_path" =~ /user\.slice/ ]] && continue (( $USER_SLICE == 0 )) && [[ "$unit_path" =~ /user\.slice/ ]] && continue # parse pidfile pids=( $(< "$pidfile") ) if (( "${#pids[*]}" == 0 )); then error "Unable to parse pid file for $svc." error "Unable to parse pid file for $service." continue fi for pid in "${pids[@]}"; do maps_path="/proc/$pid/maps" [[ -r "$maps_path" ]] || { error "Unable to read maps file of $svc for pid $pid." error "Unable to read maps file of $service for pid $pid." continue } deleted=$(grep -F '(deleted)' "$maps_path" |sed -nr 's|^\S+ ..x. \S+ \S+ \S+ \s+||p'|sort|uniq) if [[ -n $deleted ]] || { [[ -n "$busname" ]] && ! in_array "$busname" "${buses[@]}"; }; then needy+=("$svc") if (( $debug )); then echo "${c_title}Service:${c_svc} $svc${c_rst}" echo "${c_title}Pid:${c_rst} $pid" echo "${c_title}Bus:${c_rst} $busname" echo -n "${c_title}BusName matching on the system bus: ${c_rst}" in_array "$busname" "${buses[@]}" && echo 'Yes' || echo 'No' echo "${c_title}Deleted files:${c_rst}" echo "$deleted" echo fi # only file mapped as executable deleted="$(grep -F '(deleted)' "$maps_path"|sed -nr 's|^\S+ ..x. \S+ \S+ \S+ \s+||p')" if [[ $deleted ]]; then printf "%s\n" $service break fi done done } # get dbus clients on the system bus get_dbus_names() { dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply \ /org/freedesktop/DBus org.freedesktop.DBus.ListNames|sed -rn 's/\s*string "(.*)"/\1/p' } # display what we will do (( "${#needy[*]}" )) && echo '-------8<-------------------------------8<---------' for svc in "${needy[@]}"; do echo "systemctl restart '$svc'" # get systemd services not registered on dbus system bus get_missing_dbus() { local service busname local -a registered=($(get_dbus_names)) for service in $(get_services); do # get the service registered bus name busname="$(systemctl -p BusName show "$service"|cut -f 2 -d=)" if [[ "$busname" ]] && ! in_array "$busname" "${registered[@]}"; then echo $service fi done (( "${#needy[*]}" )) && echo '-------8<-------------------------------8<---------' } # start the dangerous action below if (( $restart == 1 && ${#needy[*]} > 0 )) && confirm 'Confirm service restart?'; then # display restart intruction from service name display_restart() { local service echo '-------8<-------------------------------8<---------' for service; do echo "systemctl restart '$service'" done echo '-------8<-------------------------------8<---------' } declare -A registered_pids=() declare -a running_pids=() declare -i last_registered_pids_count # restart systemd services given in arguments restart_services() { local service local -i last_registered_pids_count local -A registered_pids=() local -a running_pids=() # do the job, restart updated services for svc in "${needy[@]}"; do echo "Restarting ${c_svc}$svc${c_rst}" systemctl restart "$svc" & if (( $serialize )); then for service; do echo "systemctl restart $service" systemctl restart "$service" & if (( $SERIALIZE )); then wait # display status directly when serialize and not quiet (( $status )) && systemctl --no-pager --lines=0 status "$svc" (( $STATUS )) && systemctl --no-pager --lines=0 status "$service" else # register pids registered_pids[$!]="$svc" registered_pids[$!]="$service" fi done Loading @@ -235,7 +194,7 @@ if (( $restart == 1 && ${#needy[*]} > 0 )) && confirm 'Confirm service restart?' for pid in "${!registered_pids[@]}"; do in_array "$pid" "${running_pids[@]}" && continue # show units status (( $status )) && systemctl --no-pager --lines=0 status "${registered_pids[$pid]}" (( $STATUS )) && systemctl --no-pager --lines=0 status "${registered_pids[$pid]}" unset registered_pids[$pid] break done Loading @@ -249,18 +208,99 @@ if (( $restart == 1 && ${#needy[*]} > 0 )) && confirm 'Confirm service restart?' break fi done } # display application usage and exit 2 usage() { echo "usage ${0##*/} [options]" echo "description: check for updated files in a service" echo 'options:' echo ' -h: this help' >&2 echo " -c: auto confirmation" >&2 echo " -l/-L: call (or not) systemd daemon-reload (default: $RELOAD)" >&2 echo " -f/-F: display (or not) failed services before quit (default: $FAILED)" >&2 echo " -p/-P: call (or not) pacdiff before act (default: $PACDIFF)" >&2 echo " -r/-R: restart (or not) services with updated files (default: $RESTART)" >&2 echo " -s/-S: display (or not) status of restarted service (default: $STATUS)" >&2 echo " -u/-U: act (or not) on services in users slice (default: $USER_SLICE)" >&2 echo " -z/-Z: serialize (or not) action (default: $SERIALIZE)" >&2 exit 2 } # parse command line arguments # set options as global vars argparse() { local opt while getopts 'ahFfLlPpRrSsUuZz' opt; do case $opt in a) AUTOCONFIRM=0;; F) FAILED=0;; f) FAILED=1;; L) RELOAD=0;; l) RELOAD=1;; P) PACDIFF=0;; p) PACDIFF=1;; R) RESTART=0;; r) RESTART=1;; S) STATUS=0;; s) STATUS=1;; U) USER_SLICE=0;; u) USER_SLICE=1;; Z) SERIALIZE=0;; z) SERIALIZE=1;; *) usage;; esac done shift $((OPTIND - 1)); (( $# > 0 )) && usage } # warn if dbus was restart if in_array dbus.service "${needy[@]}"; then echo "${c_warn}After dbus restart, you should run ${0##*/} twice${c_rst}" >&2 if (( $dbus )) && [[ -z "$CHECKSERVICE_WAS_RESTARTED" ]]; then echo "${c_warn}Doing it for you. No need to thanks me!${c_rst}" >&2 export CHECKSERVICE_WAS_RESTARTED=1 exec "$0" "$@" # emulated program entry point main() { # avoid to be sighup'ed by interactive shell trap '' SIGHUP # from now, we need to be root (( $UID != 0 )) && error 'You need to be root' && exit 1 # parse command line options argparse "$@" # call pacdiff to ensure config files are updated before restart if (( $PACDIFF )); then arrow 'Run pacdiff' pacdiff fi # ensure systemd has been reloaded if (( $RELOAD )); then arrow 'Reload systemd' systemctl --system daemon-reload fi arrow 'Services with broken maps files' local -a broken_services=($(get_broken_maps)) echo "Found: ${#broken_services[@]}" if (( ${#broken_services[@]} )); then display_restart "${broken_services[@]}" if confirm 'Execute?'; then arrow 'Restart broken services' restart_services "${broken_services[@]}" fi fi arrow 'Services missing on the system bus' local -a missing_services=($(get_missing_dbus)) echo "Found: ${#missing_services[@]}" if (( ${#missing_services[@]} )); then display_restart "${missing_services[@]}" if confirm 'Execute?'; then arrow 'Restart missing services' restart_services "${missing_services[@]}" fi fi # list only failed systemd units if (( $FAILED )); then arrow "List failed units" systemctl --failed --all --no-pager --no-legend --full list-units fi } (( $failed )) && arrow "List failed units" && systemctl --failed --all --no-pager --no-legend --full list-units main "$@" exit 0