Skip to content

Instantly share code, notes, and snippets.

@nickjacob
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
Save nickjacob/9909574 to your computer and use it in GitHub Desktop.
execute arbitrary bash code/variable substitution in systemd units
[Unit]
Description=Demonstrate Bash
[Service]
ExecStartPre=/usr/bin/bash -c "/usr/bin/systemctl set-environment MYVAR=$(( 2 + 2 ))"
ExecStart=/usr/bin/echo "2 + 2 = ${MYVAR}"
@d-baranowski
Copy link

thx 👍

@PhilipSchmid
Copy link

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

https://gist.github.com/PhilipSchmid/55e40dba4e323e9236a1101a7d0d6abb

@dtrv
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.

@zffocussss
Copy link

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

@maffe
Copy link

maffe commented Apr 27, 2022

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

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

@mjtiempo
Copy link

Thanks. I use it to finally make tigervnc work with SDDM:
https://gist.github.com/mjtiempo/8662e88da74236c58115bed5cc78ceaf

@KalanaDananjaya
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.

EnvironmentFile=/tmp/timestamp.txt
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