Skip to content

Instantly share code, notes, and snippets.

@alexdlaird
Last active December 21, 2021 19:54
Show Gist options
  • Save alexdlaird/b5ccbd02a3cae0529427 to your computer and use it in GitHub Desktop.
Save alexdlaird/b5ccbd02a3cae0529427 to your computer and use it in GitHub Desktop.
Useful as a starting point for a Linux service script. The parameters in the header comments (service-name, chkconfig, etc.) are specific to Red Hat-like Linux distributions and would be ignored in a Debian environment. Make script executable and place in /etc/init.d, then run appropriate chkconfig or update-rc.d command to add as a service.
#!/bin/sh
#
# service-name Service Name and brief description
#
# chkconfig: 2345 96 06
# description: Service Name and brief description
# processname: service-name
###########################################################################
# Modify the below variables do determine how the service is run
###########################################################################
# Define here variables that may be modified to customize the service
STARTUP_TIMEOUT=60 # Seconds
STOP_TIMEOUT=30 # Seconds
###########################################################################
# Do not modify below this point unless you know what you're doing!
###########################################################################
# Ensure our environment variables are set
source /etc/profile
NAME=service-name
# NOTE: this script assumes $SERVICE_HOME is defined in /etc/profile
PID_FILE="$SERVICE_HOME/$NAME.pid"
BIN_PATH="$SERVICE_HOME/bin/$NAME"
LOG_DIR="$SERVICE_HOME/logs"
OUT_FILE="$SERVICE_HOME/$NAME.out"
RETVAL=0
start() {
if status $1; then
RETVAL=1
# Only attempt to start the service if it is not already running
else
# Check if the log file already exists and is owned by another user
if [ -e $OUT_FILE ] && [ ! -O $OUT_FILE ]; then
echo "the log file is owned by another user; run \"service $NAME clear-logs\" first."
RETVAL=1
else
# NOTE: here implement the code to start your service and store the process ID in $PID
echo -n "starting $NAME ..."
# counter=0
# while ! $started; do
# # check to set $started if service is up
#
# sleep 1
# echo -n "."
#
# ((++counter))
# if [ $counter == $STARTUP_TIMEOUT ]; then
# break
# fi
# done
# Report whether the service started successfully
if sudo kill -0 $PID > /dev/null 2>&1 && [ $counter != $STARTUP_TIMEOUT ]; then
printf " STARTED\n$NAME started as PID $PID."
else
printf " !\nan error occurred, the $NAME startup process may not have completed\ncheck PID $PID and the logs"
fi
PID=$!
echo $PID > $PID_FILE
echo "$NAME started as PID $PID."
fi
fi
}
stop() {
# Only attempt to stop the service if it is currently running
if status $1; then
PID=`cat $PID_FILE`
# NOTE: depending on the service started, there may be a more specific way to stop than gracefully terminating the process
echo -n "stopping $NAME ..."
STOP_TIMEOUT_DEC=$((STOP_TIMEOUT*10))
counter=0
# Loop until the service is stopped, ro we reach our timeout
while sudo kill -15 $PID > /dev/null 2>&1; do
sleep 0.1
echo -n "."
((++counter))
if [ $counter == $STOP_TIMEOUT_DEC ]; then
break
fi
done
# Report whether the service stopped successfully
if ! sudo kill -0 $PID > /dev/null 2>&1; then
sudo rm -f $PID_FILE
else
printf "!\nthe service didn't stop within a reasonable amount of time"
fi
else
RETVAL=1
fi
}
restart() {
stop
start
}
tail_log() {
if [ -e $OUT_FILE ]; then
tail -f $OUT_FILE
else
echo "no log file to tail; execute \"service $NAME status\" to ensure the service is running."
fi
}
clear_logs() {
# Logs shouldn't be cleared if the service is running
if status $1; then
echo "stop $NAME before attempting to clear logs"
RETVAL=1
else
# Clear logs if the logs folder isn't empty
if [ -e $OUT_FILE ]; then
sudo rm $OUT_FILE
echo "removed log $OUT_FILE"
else
echo "no logs to clear for this service"
fi
fi
}
status() {
running=1
# Check if a PID file exists, which indicates our process is running
if [ -e $PID_FILE ]; then
PID=`cat $PID_FILE`
# Ensure the value stored in the PID file is a process that is currently running
if sudo kill -0 $PID > /dev/null 2>&1; then
running=0
else
# In this case, our PID file is out of sync and the process is not actually
# running, so remove the PID
sudo rm -f $PID_FILE
if ! [ -e $PID_FILE ]; then
echo "removed zombie file for PID $PID"
fi
fi
fi
# Status report
if [ $running == 0 ]; then
echo "$NAME running as PID $PID"
else
echo "$NAME is stopped"
fi
return $running
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
log)
tail_log
;;
clear)
clear_logs
;;
status)
status
;;
*)
echo "Usage: service $NAME {start|stop|restart|log|clear|status}" >&2
RETVAL=1
;;
esac
exit $RETVAL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment