Skip to content

Instantly share code, notes, and snippets.

@gatopeich
Created March 29, 2019 12:29
Show Gist options
  • Save gatopeich/f440681a60b9ff59a8ee830554ac45f4 to your computer and use it in GitHub Desktop.
Save gatopeich/f440681a60b9ff59a8ee830554ac45f4 to your computer and use it in GitHub Desktop.
Generic Linux service script, systemd and LSB compatible but also working on older systems
#!/bin/bash
# Generic Linux service script, systemd and LSB compatible but also working on older systems
# To install:
# 1. Place under /etc/init.d/ with the name of the service
# 2. sudo chmod +x /etc/init.d/my_service
# 3. sudo systemctl enable my_service || sudo chkconfig --add my_service
# 4. sudo service my_service start
### BEGIN INIT INFO
# Provides: my_service
# Required-Start: $network
# Required-Stop: $network
# Should-Start: $named $syslog
# Should-Stop: $named $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My service
### END INIT INFO
# For (old?) RedHat distros:
# chkconfig: 2345 20 80
# http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
# http://www.thegeekstuff.com/2012/03/lsbinit-script
# Using the lsb functions if available...
LSB=/lib/lsb/init-functions
if [[ -r $LSB ]]; then
. $LSB
else
# Otherwise make stubs based on RedHat-style chkconfig/init.d
unset LSB
. /etc/init.d/functions
if type echo_success &>/dev/null; then
log_success_msg() { echo_success; echo "$@"; }
log_warning_msg() { echo_warning; echo "$@"; }
log_failure_msg() { echo_failure; echo "$@"; }
else
log_success_msg() { echo "SUCCESS: $@"; }
log_warning_msg() { echo "WARNING: $@"; }
log_failure_msg() { echo "FAILURE: $@"; }
fi
fi
# Process name ( For display )
NAME=my_service
# Daemon name, where is the actual executable
SERVICE_HOME=/opt/my_service
DAEMON="$SERVICE_HOME/my_service"
test -x $DAEMON || exit 5 # Program not installed
PIDFILE=/var/run/my_service.pid
LOGFILE=/var/log/my_service.log
# Configuration options
SERVICE_OPTIONS="--config \"$SERVICE_HOME/my_service.conf\""
#TODO: Run with non-root user / downgrade privileges
# Multi-platform status method. Silent on LSB
status() {
if [[ ! -e $PIDFILE ]]; then
[[ ! $LSB ]] && echo "my_service is not running"
return 3
elif [[ -e /proc/$(cat "$PIDFILE" 2>/dev/null) ]]; then
[[ ! $LSB ]] && echo "my_service is running"
return 0
fi
[[ ! $LSB ]] && log_warning_msg "my_service is dead"
return 1
}
start() {
if (status &>/dev/null); then
log_success_msg "my_service already started"
return 0
fi
parse_options
nohup "$DAEMON" "${SERVICE_OPTIONS[@]}" >>"$LOGFILE" 2>&1 &
echo $! > $PIDFILE
sleep .5 # Give it some time to fail if port already taken etc.
if (status &>/dev/null); then
log_success_msg "my_service started"
return 0
fi
log_failure_msg "my_service FAILED to start (status=$?)"
rm -f $PIDFILE
return 1
}
stop() {
if (status &>/dev/null); then
PID=$(cat "$PIDFILE" 2>/dev/null)
kill $PID
sleep .1
WAIT=0
while [[ -e /proc/$PID ]]; do
log_warning_msg "Waiting for my_service to finish..."
if [[ $((++WAIT)) -ge 3 ]]; then
log_failure_msg "Cannot stop my_service"
return 1
fi
sleep 1
done
fi
if (rm -f $PIDFILE &>/dev/null); then
log_success_msg "my_service is stopped"
return 0
fi
log_warning_msg "Cannot remove $PIDFILE"
return 1
}
case "$1" in
start)
#LSB: start_daemon -n 1 -p "$pidfile" "$DAEMON"
start
;;
stop)
#LSB: killproc -p "$pidfile" "$DAEMON"
stop
;;
restart)
stop
start
;;
reload)
echo "Not implemented" >&2
exit 1
;;
status)
#LSB: pidofproc -p "$pidfile" "$DAEMON"
status
state=$?
# On non-LSB systems, provide at least basic process info
[[ ! $LSB && $state == 0 ]] && ps wup $(cat "$PIDFILE" ) 2>/dev/null
exit $state
;;
*)
echo "Usage: $0 {start|stop|status|restart}" >&2
exit 1
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment