diff --git a/ssm b/ssm index e537d02..2431c50 100755 --- a/ssm +++ b/ssm @@ -5,6 +5,26 @@ shopt -s nullglob is_function() [[ "$(type -t "$1" 2>/dev/null)" == 'function' ]] readonly -f is_function +command_not_found_handle() { + declare f=$1; shift; declare argv=( "$@" ) + + # Skip the special name 'source'. + # Don't call your functions 'source'. + declare i + for i in "${FUNCNAME[@]:1}"; do + [[ $i == 'source' ]] && continue + f="${i}${f}" + break + done + + is_function "$f" || { + printf '%s: line %s: %s: command not found\n' "$0" "${BASH_LINENO[0]}" "$f" >&2 + return 127 + } + + "$f" "${argv[@]}" +}; readonly command_not_found_handle; + usage() { cat <<- EOF Usage: ssm @@ -156,12 +176,14 @@ cgroup_get_procs() { }; readonly -f cgroup_get_procs ## Run the command and wait for it to die + svc() { declare job_pid job_exit job_success last_respawn fail_counter date counter p var job_pid job_exit job_success last_respawn fail_counter date counter p svc::cleanup() { - nullexec kill -n "$service_stop_signal" "$job_pid" + #nullexec kill -n "$service_stop_signal" "$job_pid" + nullexec "${service_stop_command[@]}" anywait "$job_pid" "$service_stop_timeout" @@ -285,7 +307,7 @@ svc() { }; readonly -f svc ## Run a command with its output discarded -nullexec() { "$@" &>/dev/null; } +nullexec() { eval "$@" &>/dev/null; } readonly -f nullexec ## Wait for a pid, indefinitely @@ -490,18 +512,17 @@ stop() { fi } +info.item() { printf "%16s: %s\n" "$1" "$2"; } info() { declare -a _info_items declare _status_code _status _show_pid var _info_items _status_code _status _show_pid - info::item() { printf "%16s: %s\n" "$1" "$2"; } - - info::item Name "$service_name" + .item Name "$service_name" status; _status_code = "$?" if service_oneshot; then - info::item Oneshot 'yes' + .item Oneshot 'yes' case $_status_code in (0) _status = 'success';; @@ -510,7 +531,7 @@ info() { (*) _status = 'unknown';; esac else - info::item Restart "$service_respawn" + .item Restart "$service_respawn" case $_status_code in (0) _status = 'running';; @@ -522,23 +543,23 @@ info() { esac fi - info::item Status "$_status" + .item Status "$_status" - info::item Exec "${service_command[*]}" - info::item Config "$service_config" - info::item Workdir "$service_workdir" + .item Exec "${service_command[*]}" + .item Config "$service_config" + .item Workdir "$service_workdir" - info::item 'Output log' "$service_logfile_out" + .item 'Output log' "$service_logfile_out" service_logfile_out == "$service_logfile_err" || \ - info::item 'Error log' "$service_logfile_err" + .item 'Error log' "$service_logfile_err" if service_running; then - info::item PID "$service_pid" - info::item PIDFile "$service_pidfile" + .item PID "$service_pid" + .item PIDFile "$service_pidfile" cgroups && { - info::item Cgroup "$cgroup_home/$service_cgroup_name" - info::item 'Cgroup procs' "${#service_cgroup_procs[@]}" + .item Cgroup "$cgroup_home/$service_cgroup_name" + .item 'Cgroup procs' "${#service_cgroup_procs[@]}" } fi @@ -637,6 +658,7 @@ var XDG_RUNTIME_DIR := "/run/user/$UID" var service_respawn = 'no' # Respawn the service if it exits var service_workdir = '/' var service_stop_timeout = 30 +var service_stop_command = kill -n "\$service_stop_signal" "\$job_pid" var service_ready_timeout = 15 var service_signals = 1 10 12 var service_reload_signal = 1