Anatomy of a typical service

The atd service in the services collection is an example of a typical and commonly used regular service. Its start, stop, and restart programs are fairly trivial and straightforward. They just chain to the true command, which is effectively a no-operation for start and stop and which indicates in restart that the service should always be automatically restarted should it terminate. The meat of the service is its run program.

% system-control cat atd
start:#!/bin/nosh
start:true
stop:#!/bin/nosh
stop:true
run:#!/bin/nosh
run:#Deferred execution scheduler
run:atd -f
restart:#!/bin/sh
restart:exec true	# ignore script arguments
%

Here's its run program alone:

#!/bin/nosh
#Deferred execution scheduler
atd -f

run programs need not be scripts, but usually are in the daemontools world. They are often shell scripts, but (as here) they need not be. This run script, like most of the script files in the pre-packed service bundles, uses nosh as its script interpreter. The needs of run scripts are fairly simple, and they don't actually need the capabilities of a fully-fledged shell. They never need the capabilities of a fully-fledged shell that has a complex interactive mode and a raft of startup scripts that are sourced.

A script interpreter for a run script will thus generally be a tool designed for this purpose such as nosh or Laurent Bercot's execlineb, a script interpreter such as Python or Perl, or a lightweight shell such as the Almquist or (the lightweight, non-interactive, flavour of) the MirBSD Korn shell.

This nosh script is one of the simplest. nosh just directly chain loads the service program proper. In more complex services one might include utility commands for (amongst other things) setting environment variables from configuration files (read-conf), changing working directory (chdir), dropping root privileges and running as a dedicated user that owns no files nor directories (setuidgid), or redirecting standard open file descriptors (fdredir).

An important thing to remember is that the interpreter process itself is considered to be the service by the service manager. It must usually chain load the service program proper, as its final step. With nosh or execlineb as the script interpreter, this happens as a matter of course. With a shell program as the script interpreter, one must remember to run the service program proper with the shell's built-in exec command.

Looking at the rest of the service bundle, one finds the standard things for a "regular" service. The service is auto-started (when enabled) by the "workstation" system target. It is stopped by the "shutdown" system target. It requires for correct operation that all services in the "basic" system target be started, before it itself is started. Its output is sent to a logger service.