Skip to content

Instantly share code, notes, and snippets.

@nealian
Last active March 15, 2018 09:14
Show Gist options
  • Save nealian/4219ce02189e3abaad3c66dcaa1b2c3b to your computer and use it in GitHub Desktop.
Save nealian/4219ce02189e3abaad3c66dcaa1b2c3b to your computer and use it in GitHub Desktop.
A but.sh template to generate a systemd unit file (such as .service)

systemd-unit file buttemplate

This is a but.sh template for creating a systemd unit file (.automount, .device, .mount, .path, .scope, .service, .slice, .socket, .swap, .timer, ...)

Prerequisites

This, of course, requires but.sh The template itself requires only bash and gnu-coreutils.

Variables

The valid section names are:

  • Automount
  • Install
  • Mount
  • Path
  • Scope
  • Service
  • Slice
  • Socket
  • Swap
  • Timer
  • Unit

Variables are named like <section_name_allcaps>_<option_name>, where the option name is also all-caps and words separated by underscores. (Example: SERVICE_GUESS_MAIN_PID would match GuessMainPID in the [Service] section.)

If any variables are defined in a given section, the section is created; they are defined in the alphabetical order.

Examples

All of the .env files in this gist are examples for unit files of the stated type.

Downloading

wget https://gist.github.com/nealian/4219ce02189e3abaad3c66dcaa1b2c3b/raw/systemd-unit.buttemplate{,.src}

Usage

but.sh systemd-unit.buttemplate -c systemd-unit.buttemplate.src -c unit.env -o /usr/lib/systemd/system/unit.service
AUTOMOUNT_WHERE=/path/to/automount
AUTOMOUNT_DIRECTORY_MODE=0750
INSTALL_WANTED_BY=multi-user.target
UNIT_DESCRIPTION="Automount /path/to/automount"
MOUNT_WHAT="nfs.example.com:/export/foo"
MOUNT_WHERE=/path/to/mount
MOUNT_TYPE=nfs
MOUNT_DIRECTORY_MODE=0750
INSTALL_WANTED_BY=multi-user.target
UNIT_DESCRIPTION="Mount /path/to/mount"
PATH_PATHCHANGED=/path/to/watch
INSTALL_WANTED_BY=default.target
SERVICE_TYPE=simple
SERVICE_EXEC_START="/path/to/binary %i"
SERVICE_STANDARD_INPUT=socket
SERVICE_STANDARD_ERROR=journal
UNIT_DESCRIPTION="Mount /path/to/mount"
UNIT_REQUIRES=foo.socket
SOCKET_LISTEN_STREAM="127.0.0.1:31337"
SOCKET_ACCEPT=yes
INSTALL_WANTED_BY=sockets.target
UNIT_DESCRIPTION="Socket for per-socket service"
SWAP_WHAT=/dev/sda3
INSTALL_WANTED_BY=swap.target
UNIT_DESCRIPTION="Swap at /dev/sda3"
$(for x in ${SECTIONS_SYSTEMD[*]}; do
opts=$(eval echo "\${!${x^^}_*}")
if [[ -n "${opts}" ]]; then
echo "[${x}]";
for y in ${opts}; do
echo "$(echo ${y##${x^^}_} | sed -r 's,^([A-Z]+)(_?),\L\u\1\2,;s,_([A-Z]+),\L\u\1,g' | sed "$(for repl in ${nosep[*],,}; do echo "s,${repl^},${repl^^},g;"; done)" | sed 's,SELINUX,SELinux,g')=${!y}";
done;
echo;
fi;
done)
declare -a SECTIONS_SYSTEMD
SECTIONS_SYSTEMD=(Automount Install Mount Path Scope Service Slice Socket Swap Timer Unit)
declare -a nosep=(TTYVT TTYV TTY STACK SIGPIPE SIGPENDING SIGKILL SIGHUP SELINUX RTTIME RTPRIO RSS PID PAM OOM NPROX NOFILE NICE MSGQUEUE MEMLOCK LOCKS IPTTL IPTOS IP IO FSIZE FIFO DATA CPU CORE AS AC)
TIMER_ON_BOOT_SEC=15min
TIMER_ON_UNIT_ACTIVE_SEC=1w
INSTALL_WANTED_BY=timers.target
UNIT_DESCRIPTION="Run example service 15 minutes after boot and again every week while the system is running"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment