I have a systemd service that needs to create a directory in /run, but otherwise run as a non-root user. From a blog example, I derived the following solution:

[Unit]
Description=Startup Thing

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 -u /opt/thing/doStartup
WorkingDirectory=/opt/thing
StandardOutput=journal
User=thingUser
# Make sure the /run/thing directory exists
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /run/thing
ExecStartPre=/bin/chmod -R 777 /run/thing

[Install]
WantedBy=multi-user.target

The magic is in the 3 lines that follow the comment. Apparently the ExecStartPre's will run as root this way, but the ExecStart will run as the specified user.

This has lead to 3 questions though:

  1. What does the - do in front of the /bin/mkdir? I don't know why it's there or what it does.
  2. When there are multiple ExecStartPre's in a unit file, are they just run serially in the order that they are found in the unit file? Or some other method?
  3. Is this actually the best technique to accomplish my goal of getting the run directory created so that the non-root user can use it?
up vote 22 down vote accepted

For any questions about a systemd directives, you can use man systemd.directives to lookup the man page that documents the directive. In the case of ExecStartPre=, you'll find it documented in man systemd.service.

There in docs for ExecStartPre=, you'll find it explained that the leading "-" is used to note that failure is tolerated for these commands. In this case, it's tolerated if /run/thing already exists.

The docs there also explain that "multiple command lines are allowed and the commands are executed one after the other, serially."

One improvement to your method of pre-creating the directory is not make it world-writable when you only need it to be writable by a particular user. More limited permissions would be accomplished with:

 ExecStartPre=-/bin/chown thingUser /run/thing
 ExecStartPre=-/bin/chmod 700       /run/thing

That makes the directory owned by and fully accessible from a particular user.

  • Awesome answer, thank you for the systemd.directives hint, I always find systemd difficult to figure out where to go. That helps. – Travis Griggs Mar 1 '17 at 18:27
  • 1
    You should probably cover RuntimeDirectory and RuntimeDirectoryMode too. – JdeBP Mar 1 '17 at 19:34

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.