Skip to content

Instantly share code, notes, and snippets.

Last active March 17, 2023 16:11
  • Star 78 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
execute arbitrary bash code/variable substitution in systemd units
Description=Demonstrate Bash
ExecStartPre=/usr/bin/bash -c "/usr/bin/systemctl set-environment MYVAR=$(( 2 + 2 ))"
ExecStart=/usr/bin/echo "2 + 2 = ${MYVAR}"
Copy link

Thanks! Used it to dynamically set a USB Ethernet dongle to a separate namespace:

Copy link

dtrv commented May 22, 2020

Note it won't work if user is not root (i.e. if you define "User" in [Service] section). It can be fixed with "PermissionsStartOnly=true", so all commands will be executed as root, and ExecStart command will be run as the defined user as intended.

add --user to systemctl and it works.

Copy link

nice! I have a question why does env variables generated by ExecStartPre can be used by ExecStart?

Copy link

maffe commented Apr 27, 2022

I prefer to write the variable to a file specific to this unit:

ExecStartPre=/usr/bin/bash -c "echo MYVAR=$(( 2 + 2 )) >/dev/shm/demo.env"
ExecStart=/usr/bin/echo "2 + 2 = ${MYVAR}"

Copy link

Thanks. I use it to finally make tigervnc work with SDDM:

Copy link

KalanaDananjaya commented Mar 17, 2023

Beware that there's a pitfall if you have to use %s with your command.
echo (date +%s)
SystemD sees this as user shell and resolve to /bin/sh instead. You need to use %%s to avoid that.

ExecStartPre=/bin/bash -c "echo TIMESTAMP=$(date +%%s) > /tmp/timestamp.txt;"

Although this seems simple, it was quite hard to find this info. ChatGPT was not yielding a correct result either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment