untode.su

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 -w key 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:

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: