-
-
Save jeeshofone/0f0495e8053fd1208edb425f19bb7f54 to your computer and use it in GitHub Desktop.
A template to write a quick daemon as a bash script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment