Skip to content

Instantly share code, notes, and snippets.

@nealian
Last active March 2, 2019 19:10
Show Gist options
  • Save nealian/b3e40c8a7326ebea389e5fb97b3eeea3 to your computer and use it in GitHub Desktop.
Save nealian/b3e40c8a7326ebea389e5fb97b3eeea3 to your computer and use it in GitHub Desktop.
A but.sh template to generate a SysV init script for running a .jar as a daemon

sysvinit-jar buttemplate

This is a but.sh template for creating /etc/rc.d/init.d scripts for Java jar files. (Slightly based on the EPEL init-script template, and intended for an el6 machine, though I'm sure it would work with many, many more systems.)

Other daemons?

After making this template, of course I realized that this could very easily be modified to do any other daemon, so I did just that, though it was honestly pretty trivial.

Prerequisites

This, of course, requires but.sh.

The template itself requires only bash and gnu-coreutils (for head and potentially echo).

Variables

Required:

  • NAME -- The intended name of the daemon
  • JAVA_BIN -- The path to the Java binary
  • JAR -- The path to the jar to run

Optional:

(Unless otherwise specified for the variable, assume the default is null.)

  • SUMMARY -- A very short summary of the daemon -- Defaults to the value of $NAME
  • CHKCONFIG_START_LEVELS -- A string of runlevels (ex: '2345')
  • CHKCONFIG_START_PRIORITY -- The starting priority, from 0-100 (0: started first) -- Defaults to 100
  • CHKCONFIG_STOP_PRIORITY -- The stopping priority, from 0-100 (0: stopped first) -- Defaults to 0
  • DESCRIPTION -- A longer description of the daemon, with lines separated by \n (see the manpage for echo for more backslash-sequences)
  • LSB_PROVIDES -- The name(s) of the facilities that this daemon provides -- Defaults to the value of $NAME
  • LSB_REQUIRED_START -- The name(s) of the facilities that this daemon needs to have running to be able to start
  • LSB_REQUIRED_STOP -- The name(s) of the facilities that this daemon needs to have STILL running to be able to stop
  • LSB_SHOULD_START -- The name(s) of the facilities that this daemon should start after; weak requires, but without failing if they don't exist
  • LSB_SHOULD_STOP -- The name(s) of the facilities that this daemon should stop before; weak requires, but without failing if they don't exist
  • LSB_DEFAULT_START -- A space-separated list of runlevels that this daemon should start on -- Defaults to space-separated $CHKCONFIG_START_LEVELS if that variable is set, otherwise null
  • LSB_DEFAULT_STOP -- A space-separated list of runlevels that this daemon should not be running on -- Defaults to all in the range 0-6 that $LSB_DEFAULT_START does not include if $LSB_DEFAULT_START or $CHKCONFIG_START_LEVELS are set, otherwise null
  • OUTLOG -- The log output file -- Defaults to /var/log/$NAME/$NAME.out
  • ERRLOG -- The error logging file -- Defaults to /var/log/$NAME/$NAME.err
  • JAR_ARGS -- The list of arguments to pass to the Java process (for the jar)

Downloading

wget https://gist.github.com/nealian/b3e40c8a7326ebea389e5fb97b3eeea3/raw/sysvinit-jar.buttemplate && wget https://gist.github.com/nealian/b3e40c8a7326ebea389e5fb97b3eeea3/raw/sysvinit-jar.buttemplate.functions

Usage

but.sh sysvinit-jar.buttemplate -c sysvinit-jar.buttemplate.functions -c daemon.environment -o /etc/rc.d/init.d/daemon
NAME=example
JAR=/path/to/ex.jar
JAVA_BIN=/usr/bin/java
CHKCONFIG_START_LEVELS=2345
CHKCONFIG_START_PRIORITY=80
CHKCONFIG_STOP_PRIORITY=20
DESCRIPTION="Hey look, this is\n
a multiline description"
JAR_ARGS='-arg1 val1 -arg2'
#!/bin/sh
#
# ${NAME} ${SUMMARY=${NAME}}
#
# chkconfig: ${CHKCONFIG_START_LEVELS--} ${CHKCONFIG_START_PRIORITY-100} ${CHKCONFIG_STOP_PRIORITY-0}
# description: $(echo -e ${DESCRIPTION} | while read line; do echo '# ' $line '\'; done | head -c -2 | tail -c +4)
### BEGIN INIT INFO
# Provides: ${LSB_PROVIDES-${NAME}}${LSB_REQUIRED_START+"$(echo)# Required-Start: ${LSB_REQUIRED_START}"}${LSB_REQUIRED_STOP+"$(echo)# Required-Stop: ${LSB_REQUIRED_STOP}"}${LSB_SHOULD_START+"$(echo)# Should-Start: ${LSB_SHOULD_START}"}${LSB_SHOULD_STOP+"$(echo)# Should-Stop: ${LSB_SHOULD_STOP}"}$(if [[ -n "$LSB_DEFAULT_START" ]]; then echo; echo "# Default-Start: ${LSB_DEFAULT_START}"; echo "# Default-Stop: ${LSB_DEFAULT_STOP-$(lsb_determine_stop_levels)}"; elif [[ -n "$CHKCONFIG_START_LEVELS" ]]; then echo; echo "# Default-Start: $(lsb_determine_start_levels)"; echo "# Default-Stop: ${LSB_DEFAULT_STOP-$(lsb_determine_stop_levels)}"; fi)
# Short-Description: ${SUMMARY}
# Description: $(echo -e ${DESCRIPTION} | while read line; do echo '# ' $line; done | head -c -1 | tail -c +4)
### END INIT INFO
# Source function library
. /etc/init.d/functions
exec='${JAVA_BIN}'
prog='${NAME}'
outlog='${OUTLOG-/var/log/${NAME}/${NAME}.out}'
errlog='${ERRLOG-/var/log/${NAME}/${NAME}.err}'
[ -e /etc/default/\$prog ] && . /etc/default/\$prog
$([[ -n "${JAR_ARGS}" ]] && (echo; echo args+=${JAR_ARGS}; echo))
pidfile=\"/var/run/\${prog}.pid\"
pstree() {
local children=\$(pgrep -P \$1)
for x in \$children; do
echo \$x
pstree \$x
done
}
start() {
local res pid
[ -x \$exec ] || exit 5
echo -n \"Starting \$prog:\"
mkdir -p \$(dirname \$outlog) \$(dirname \$errlog)
daemon --pidfile \$pidfile \$exec -jar ${JAR} \$args >>\$outlog 2>>\$errlog &
res=\$?
pid=\$!
sleep 5
(echo \$pid; pstree \$pid) > \$pidfile
if [ \$res -eq 0 ]; then
echo_success
else
echo_failure
fi
echo
}
stop() {
local res
echo -n \"Stopping \$prog:\"
killproc -p \$pidfile \$prog
res=\$?
if [ \$res -eq 0 ]; then
echo_success
else
echo_failure
fi
echo
}
restart() {
stop
start
}
reload() {
restart
}
force_reload() {
restart
}
rh_status() {
status -p \$pidfile \$prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case \"\$1\" in
start)
rh_status_q && exit 0
\$1
;;
stop)
rh_status_q || exit 0
\$1
;;
restart)
\$1
;;
reload)
rh_status_q || exit 7
\$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo \"Usage: \$0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}\"
exit 2
esac
exit \$?
function lsb_determine_start_levels() {
_split_chars ${CHKCONFIG_START_LEVELS} ' '
}
function lsb_determine_stop_levels() {
_split_chars $(_exclude ${LSB_DEFAULT_START:-${CHKCONFIG_START_LEVELS}} '0123456') ' '
}
function _exclude() {
local a=$2
for (( i=0; i<${#1}; i++ )); do
a=${a//${1:$i:1}/}
done
echo $a
}
function _split_chars() {
for (( i=0; i<${#1}; i++ )); do
echo -n "${1:$i:1}${2}"
done | head -c -${#2}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment