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. It’s too big to paste it in the blog post so have a clickable link.

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: