Skip to content

Instantly share code, notes, and snippets.

@antonc42
Forked from shawnrice/skeleton-daemon.sh
Created August 22, 2017 14:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save antonc42/bc8162c22a046d66454707d7d85ae012 to your computer and use it in GitHub Desktop.
Save antonc42/bc8162c22a046d66454707d7d85ae012 to your computer and use it in GitHub Desktop.
A template to write a quick daemon as a bash script
#!/bin/bash
# This is a skeleton of a bash daemon. To use for yourself, just set the
# daemonName variable and then enter in the commands to run in the doCommands
# function. Modify the variables just below to fit your preference.
daemonName="DAEMON-NAME"
myPid=$$
pidDir="."
pidFile="$pidDir/$daemonName.pid"
logDir="."
# To use a dated log file.
# logFile="$logDir/$daemonName-$(date +"%Y-%m-%d").log"
# To use a regular log file.
logFile="$logDir/$daemonName.log"
# Log maxsize in KB
logMaxSize=1024 # 1mb
runInterval=60 # In seconds
doCommands() {
# This is where you put all the commands for the daemon.
echo "Running commands."
}
################################################################################
# Below is the skeleton functionality of the daemon.
################################################################################
setupDaemon() {
# Make sure that the directories work.
if [[ ! -d "$pidDir" ]]; then
mkdir "$pidDir"
fi
if [[ ! -d "$logDir" ]]; then
mkdir "$logDir"
fi
if [[ ! -f "$logFile" ]]; then
touch "$logFile"
else
# Check to see if we need to rotate the logs.
size=$(( $(stat --printf="%s" "$logFile") / 1024 ))
if [[ $size -gt $logMaxSize ]]; then
mv $logFile "$logFile.$(date +%Y-%m-%dT%H-%M-%S).old"
touch "$logFile"
fi
fi
}
startDaemon() {
# Start the daemon.
setupDaemon # Make sure the directories are there.
if ! checkDaemon; then
echo 1>&2 " * Error: $daemonName is already running."
exit 1
fi
echo " * Starting $daemonName with PID: $myPid."
echo "$myPid" > "$pidFile"
log '*** '$(date +"%Y-%m-%d")": Starting up $daemonName."
# Start the loop.
loop
}
stopDaemon() {
# Stop the daemon.
if checkDaemon; then
echo 1>&2 " * Error: $daemonName is not running."
exit 1
fi
echo " * Stopping $daemonName"
if [[ ! -z $(cat "$pidFile") ]]; then
kill -9 $(cat "$pidFile") &> /dev/null
log '*** '$(date +"%Y-%m-%d")": $daemonName stopped."
else
echo 1>&2 "Cannot find PID of running daemon"
fi
}
statusDaemon() {
# Query and return whether the daemon is running.
if ! checkDaemon; then
echo " * $daemonName is running."
else
echo " * $daemonName isn't running."
fi
exit 0
}
restartDaemon() {
# Restart the daemon.
if checkDaemon; then
# Can't restart it if it isn't running.
echo "$daemonName isn't running."
exit 1
fi
stopDaemon
startDaemon
}
checkDaemon() {
# Check to see if the daemon is running.
# This is a different function than statusDaemon
# so that we can use it other functions.
if [[ -z "$oldPid" ]]; then
return 0
elif ps -ef | grep "$oldPid" | grep -v grep &> /dev/null ; then
if [[ -f "$pidFile" && $(cat "$pidFile") -eq $oldPid ]]; then
# Daemon is running.
return 1
else
# Daemon isn't running.
return 0
fi
elif ps -ef | grep "$daemonName" | grep -v grep | grep -v "$myPid" | grep -v "0:00.00" | grep bash &> /dev/null ; then
# Daemon is running but without the correct PID. Restart it.
log '*** '$(date +"%Y-%m-%d")": $daemonName running with invalid PID; restarting."
restartDaemon
return 1
else
# Daemon not running.
return 0
fi
return 1
}
loop() {
while true; do
# This is the loop.
now=$(date +%s)
if [[ -z $last ]]; then
last=$(date +%s)
fi
# Do everything you need the daemon to do.
doCommands
# Check to see how long we actually need to sleep for. If we want this to run
# once a minute and it's taken more than a minute, then we should just run it
# anyway.
last=$(date +%s)
# Set the sleep interval
if [[ ! $((now-last+runInterval+1)) -lt $((runInterval)) ]]; then
sleep $((now-last+runInterval))
fi
done
}
log() {
# Generic log function.
echo "$1" >> "$logFile"
}
################################################################################
# Parse the command.
################################################################################
if [[ -f "$pidFile" ]]; then
oldPid=$(cat "$pidFile")
fi
checkDaemon
case "$1" in
start)
startDaemon
;;
stop)
stopDaemon
;;
status)
statusDaemon
;;
restart)
restartDaemon
;;
*)
echo 1>&2 " * Error: usage $0 { start | stop | restart | status }"
exit 1
esac
exit 0
@antonc42
Copy link
Author

Made changes and fixed bugs

@ibiwan
Copy link

ibiwan commented Jun 12, 2018

This version fixed several bugs I was experiencing with the parent copy. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment