Automating things without systemd
This year I ran into a peculiar problem: how does one daemonze a process without using any systemd related utilities (user services also won’t work because SSH sessions are not considered real sessions); the reasoning behind this bizarre problem is the way the VPS owner shares it’s usage between other people (letting people sudo around doesn’t look like a good idea)
The obvious choice in that case is to write a wrapper script which would make sure a specific process (or a screen session, I will touch on that next) is always running, and if it isn’t, the wrapper will launch it. This script should be executed at a fixed interval by putting it inside your crontab
Using nohup
The nohup utility allows you to force a process into the background without holding on to your current session. This is the simplest method of daemonizing stuff which comes at a cost of not being able to read/write process input/output streams without some dark pipe file magic.
Example script:
#!/bin/bash
processes=$(ps -o cmd)
if echo ${processes} | grep -wq PROCNAME; then exit 0; fi
nohup /usr/bin/PROCNAME ARGS > /dev/null 2>&1 &
exit 0
A pesky thing with this specific script is the need to strictly match process names because the wrapper script lists all the user processes including the wrapper script itself; to mitigate this, the
-wkey is used when grep-ing which makes the utility to only produce exact matches.
A cron job is then created to run the wrapper script at a set fixed time interval (in my case it’s every 5 minutes, it can be different); just consider your environment’s PID limit and choose the interval accordingly (in this specific case the VPS was grinding to a screeching halt when PID values exceeded 40000):
*/5 * * * * /usr/local/bin/SCRIPTNAME
Using screen
If the daemonized process needs to have an interactive standard input, using GNU screen is the best choice. GNU screen creates a detached virtual terminal session which can be then forced into the background without affecting your current session; you can also then re-attach it to your session with a simple command and detach it back with a key combination.
Example: I run a Minecraft server on the same exact VPS. The wrapper script is much more complicated and is designed to resemble a classic sysvinit script that one would place in the rc.d directory to be then called by the init process.
Let’s quickly go through all the stuff the script does:
- Passing
watchas an argument makes the script check if a specific named screen session is running and if there isn’t one, the script will create one; - Passing
startorrestartas an argument makes the script ensure there is no specific named session running, and then the script will create a new session; - Passing
stuffputs a single line followed by a LF character into the session’s standard input stream; if there isn’t a session, the script prints and error; - Passing
stopclobbers the active session, if there is one;
Cron job entries for the server look like this:
*/5 * * * * /home/und/nrmc/service.sh watch
30 19 * * * /home/und/nrmc/service.sh stuff broadcast Restarting in 30 minutes
45 19 * * * /home/und/nrmc/service.sh stuff broadcast Restarting in 15 minutes
55 19 * * * /home/und/nrmc/service.sh stuff broadcast Restarting in 5 minutes
55 19 * * * /home/und/nrmc/service.sh stuff save-all
00 20 * * * /home/und/nrmc/service.sh restart
And, as evident by the screenshots, the approach works:
