177 lines
6.4 KiB
Bash
Executable File
177 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Simple launcher script to start a worker script within a service or
|
|
# one for every service.
|
|
#
|
|
# Services are subfolders of the $SERVICE_BASE parameter set below.
|
|
# The worker script is an executable file within the service's $TOOLS_BASE
|
|
# folder. The launcher supposes that the filename of the worker script
|
|
# is the same as the launcher's.
|
|
#
|
|
# Without command line parameters the launcher enumerates all services
|
|
# and launches every service's worker script. Optionally waits between
|
|
# launches if is prescribed in $SLEEP_BETWEEN parameter. This operation
|
|
# needs to be forced by --doit command line option.
|
|
#
|
|
# With at least one command line parameter the launcher launches only one
|
|
# worker script, which is within the service named in the first parameter.
|
|
# If the supposed service or the worker script doesn't exist the script
|
|
# silently does nothing.
|
|
#
|
|
# Normally the launcher starts the worker(s) in background, then exits.
|
|
# Using the --wait command line option you may wait for the worker(s)
|
|
# and get exit code 1 if any worker has reported some error.
|
|
#
|
|
# You may call this script from the cron - in this case must be set
|
|
# the CRON environment variable in crontab and must be exported to the script.
|
|
#
|
|
# Author: Kovács Zoltán <kovacs.zoltan@smartfront.hu>
|
|
# Kovács Zoltán <kovacsz@marcusconsulting.hu>
|
|
# License: GNU/GPL v3+ (https://www.gnu.org/licenses/gpl-3.0.en.html)
|
|
# 2023-06-18 v1.0
|
|
# new: forked from the "SMARTERP_skeleton" repository.
|
|
# mod: "instance" => "service"
|
|
# 2022-08-03 v0.6
|
|
# new: it optionally waits for the worker(s) and returns with exit code 1,
|
|
# if it has got at least one non-zero exit code from them.
|
|
# 2021-02-15 v0.5
|
|
# fix: omits the error message when there is no services at all
|
|
# 2021-02-05 v0.4
|
|
# fix: proper $PATH settings in Debian environment as well
|
|
# 2021-02-04 v0.3
|
|
# fix: decimal point trouble in non-english environments (eg. Hungarian)
|
|
# 2021-01-05 v0.2
|
|
# fix: LANG=C and LC_ALL=C initialisations have removed, because these may
|
|
# interfere with UTF-8 file name encoding in Java calls:
|
|
# https://ogris.de/howtos/java-utf8-filenames.html
|
|
# 2020-11-20 v0.1 Initial release
|
|
|
|
# Accepted environment variables and their defaults.
|
|
#
|
|
CRON=${CRON-""} # Does it run from cron?
|
|
SERVICE_BASE=${SERVICE_BASE-"$HOME/services"} # Services' folder path
|
|
SLEEP_BETWEEN=${SLEEP_BETWEEN-"0"} # Secs between forks
|
|
|
|
# There is nothing to configure below (I hope).
|
|
###############################################
|
|
|
|
# Messages.
|
|
#
|
|
MSG_BADOPT="Invalid option"
|
|
MSG_MISSINGDEP="Fatal: missing dependency"
|
|
MSG_USAGE="For one service: $($(which basename) "$0") [--wait] servicename\n"
|
|
MSG_USAGE+="For all services: $($(which basename) "$0") [--wait] --doit\n"
|
|
MSG_USAGE+="Environment variables:\n"
|
|
MSG_USAGE+=" SERVICE_BASE Absolute path to the folder containing services\n"
|
|
MSG_USAGE+=" (default: \$HOME/services)\n"
|
|
MSG_USAGE+=" SLEEP_BETWEEN Secs (may fraction) to wait between multiple launches\n"
|
|
MSG_USAGE+=" (default: 0.0)"
|
|
|
|
# Getting command line options.
|
|
DOIT="" # Enables launch processes for all available services.
|
|
WAIT="" # Wait for the result of the actually launched process.
|
|
while getopts ":-:" option
|
|
do
|
|
case ${option} in
|
|
"-" )
|
|
if [ "$OPTARG" = "doit" ]; then DOIT="yes"
|
|
elif [ "$OPTARG" = "wait" ]; then WAIT="yes"
|
|
else echo "$MSG_BADOPT --$OPTARG" >&2; exit 1
|
|
fi
|
|
;;
|
|
\? )
|
|
echo "$MSG_BADOPT -$OPTARG" >&2; exit 1
|
|
;;
|
|
esac
|
|
done; shift $((OPTIND -1))
|
|
# Done with options.
|
|
|
|
# Basic environment settings.
|
|
#
|
|
# Corrects the PATH if the operating system didn't loaded yet;
|
|
# it is a bug with cron pam_env, I think.
|
|
if [ -n "$CRON" ]; then
|
|
[[ -r "/etc/profile" ]] && source "/etc/profile"
|
|
# Ubuntu gets the initial environment from a separate file.
|
|
if [ -r "/etc/environment" ]; then
|
|
# Extracts from this file, strips the right part w/o quotes.
|
|
includepath=$(cat "/etc/environment" | $(which egrep) '^PATH=')
|
|
includepath=${includepath:5}
|
|
includepath="${includepath%\"}"; includepath="${includepath#\"}"
|
|
[[ -n "$includepath" ]] && PATH="$PATH:$includepath"
|
|
unset includepath
|
|
fi
|
|
# We need the $HOME/bin as well.
|
|
PATH="$HOME/bin:$PATH"
|
|
fi
|
|
# We need also the sbin directories.
|
|
if ! [[ "$PATH" =~ '/sbin:' ]]; then PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin"; fi
|
|
|
|
# Checks the dependencies.
|
|
#
|
|
TR=$(which tr 2>/dev/null)
|
|
if [ -z "$TR" ]; then echo "$MSG_MISSINGDEP tr."; exit 1 ; fi
|
|
#for item in basename df egrep head mail printf sleep
|
|
for item in basename printf sleep
|
|
do
|
|
if [ -n "$(which $item)" ]
|
|
then export $(echo $item | "$TR" '[:lower:]' '[:upper:]')=$(which $item)
|
|
else echo "$MSG_MISSINGDEP $item." >&2; exit 1; fi
|
|
done
|
|
# All dependencies are available via "$THECOMMAND" (upper case) call.
|
|
|
|
# Initializations and sanitizations.
|
|
#
|
|
if [ -z "$SERVICE_BASE" -o ! -d "$SERVICE_BASE" ]; then exit 1; fi
|
|
SLEEP_BETWEEN=$("$PRINTF" '%.2f' "$SLEEP_BETWEEN" 2>/dev/null) # To float
|
|
TOOLS_BASE="tools" # Relative path
|
|
WORKERFILE="$("$BASENAME" "$0")" # Same filename
|
|
|
|
# Collects the service(s).
|
|
if [ -n "$1" ]; then
|
|
# One service.
|
|
SERVICES="$1/"; shift
|
|
elif [ -n "$DOIT" ]; then
|
|
# All services when has forced.
|
|
SERVICES="$(cd "$SERVICE_BASE"; ls -d */ 2>/dev/null)"
|
|
else
|
|
echo -e "$MSG_USAGE" >&2; exit 1
|
|
fi
|
|
|
|
# Prepares to save the result codes.
|
|
declare -A JOBS
|
|
# Eumerates the service folders.
|
|
[[ -z "$SERVICES" ]] && exit
|
|
for service in $SERVICES ""
|
|
do
|
|
# Safety first...
|
|
if [ -n "$service" ]; then
|
|
# Forks the worker if it does exist and does runnable.
|
|
if [ -x "$SERVICE_BASE/$service$TOOLS_BASE/$WORKERFILE" ]; then
|
|
# Sets PATH and USER, passes all remaining command line parameters.
|
|
[[ -n "$CRON" ]] && export PATH USER
|
|
"$SERVICE_BASE/$service$TOOLS_BASE/$WORKERFILE" "$@" &
|
|
PID="$!"
|
|
# Optionally waits for the worker and saves the result.
|
|
if [ -n "$WAIT" ]
|
|
then wait $PID; JOBS["$service"]=$?; fi
|
|
# Optionally reduces the fork frequency.
|
|
"$SLEEP" ${SLEEP_BETWEEN//,/.} # decimal point need
|
|
else
|
|
# Optionally reports the failure.
|
|
if [ -n "$WAIT" ]
|
|
then JOBS["$service"]=1; fi
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Optionally returns with exit code 1, if it has got at least one
|
|
# non-zero exit code from workers.
|
|
if [ -n "$WAIT" ]; then
|
|
for key in "${!JOBS[@]}"
|
|
do [[ "${JOBS[$key]}" -gt 0 ]] && exit 1
|
|
done
|
|
fi
|
|
|
|
# That's all, Folks! :)
|