I think your systemd setup is correct. If the terminal hangs when you start the service then I would suspect the ExecStartPre
command is not exiting.
I ran the following commands as root on an Ubuntu 20.04 server to test a similar service setup.
Create a user for the service.
useradd --system myservice
Create a script for the service that logs the user the script is running as and loops.
cat <<'EOF' > /usr/local/bin/myservice.sh
#!/usr/bin/env bash
# first argument is loop count, defaults to infinite
i=${1:--1}
while :; do
date >> ${RUNTIME_DIRECTORY:-/tmp}/run.log
whoami >> ${RUNTIME_DIRECTORY:-/tmp}/run.log
(( --i == 0 )) && break
sleep ${SLEEP:-60}
done
EOF
Add the service file and the override file.
cat <<EOF > /etc/systemd/system/myservice.service
[Unit]
Description=My Service
[Service]
EnvironmentFile=-/etc/default/myservice
Type=simple
User=myservice
Group=myservice
Restart=on-failure
RuntimeDirectory=myservice
RuntimeDirectoryMode=0750
ExecStart=/bin/bash /usr/local/bin/myservice.sh
EOF
mkdir -p /etc/systemd/system/myservice.service.d/
cat <<EOF > /etc/systemd/system/myservice.service.d/override.conf
[Service]
PermissionsStartOnly=true
ExecStartPre=/bin/bash /usr/local/bin/myservice.sh 1
ExecStartPre=chown myservice.myservice /run/myservice/run.log
EOF
systemctl daemon-reload
Start the service
systemctl start myservice.service
The result is as expected. The run.log
file shows the script ran once as root
and then continues running as the myservice
user until the service is stopped.
root@ubuntu:~# ls -al /run/myservice/
total 4
drwxr-x--- 2 myservice myservice 60 Feb 27 18:23 .
drwxr-xr-x 30 root root 1080 Feb 27 18:23 ..
-rw-r--r-- 1 myservice myservice 73 Feb 27 18:23 run.log
root@ubuntu:~# cat /run/myservice/run.log
Sun Feb 27 18:23:14 UTC 2022
root
Sun Feb 27 18:23:14 UTC 2022
myservice
Sun Feb 27 18:24:14 UTC 2022
myservice
I did find that if the ExecStartPre
command enters the loop then the terminal appears to hang when the service is started. That could explain why you think your service is freezing. The ExecStartPre
command may still be running or may be unable to complete.
Other Notes
- I found that using either
PermissionsStartOnly=true
or ExecStartPre=+...
had the same effect of running the ExecStartPre
script as root.