8

My unit file looks like this (already attempted to escape spaces as \x20 like the docs say):

[Unit]
Description=My Service

[Service]
Type=simple
WorkingDirectory=/home/cobra/my\x20service/
ExecStart=/home/cobra/my\x20service/start.sh

[Install]
WantedBy=multi-user.target

but when attempting to start it, it fails with the following message:

Failed at step CHDIR spawning /home/cobra/my service/start.sh: No such file or directory
myservice.service: main process exited, code=exited, status=200/CHDIR

Giving the path from this error message to stat returns:

  File: ‘/home/cobra/my service/start.sh’
  Size: 280             Blocks: 8          IO Block: 4096   regular file
Device: 903h/2307d      Inode: 4718912     Links: 1
Access: (0754/-rwxr-xr--)  Uid: ( 1000/   cobra)   Gid: ( 1000/   cobra)
Access: 2015-05-24 22:42:12.702657594 +0200
Modify: 2015-03-27 22:28:05.682531000 +0100
Change: 2015-05-24 22:40:58.830298787 +0200
 Birth: -

I cannot remove the spaces from the file name as the service I'm attempting to run requires them for some reason.

Where am I going wrong?

5
  • Have you tried backslash space ("\ ") like the shell?
    – hookenz
    May 24, 2015 at 23:19
  • @Matt Yes, same error as above, except the backslash is visible in the path presented in the errormessage.
    – Cobra_Fast
    May 24, 2015 at 23:21
  • It seems that spaces are used as a way of separating arguments. And googling this returns some ugly workarounds. Can you change the path? otherwise what about trying a non-space separated symbolic link as the path name which points to the real directory?
    – hookenz
    May 24, 2015 at 23:27
  • 1
    Well I did find a tool called systemd-escape which allows you to create paths. It seems / gets changed to dash.
    – hookenz
    Jun 4, 2015 at 2:17
  • Did you figure out how to get WorkingDirectory to work with spaces? Nothing is working for me. Jul 16, 2020 at 2:08

3 Answers 3

11

The correct way to generate paths in systemd is to use systemd-escape.

i.e.

~$ systemd-escape --path "/home/cobra/my service/start.sh"
home-cobra-my\x20service-start.sh

Yes / gets replaced with -

3
  • in my case I only needed to escape the path for the WorkingDirectory setting using the systemd-escape command before my service worked. is it best practice to escape paths used in the ExecStart setting with the command as well or does is it fine to just use quotes as long as it works?
    – intcreator
    Aug 22, 2021 at 15:56
  • 1
    I would use quotes if possible. But failing that, this tool. In the end you need to try something that works. In my opinion, systemd-escape is a funny tool that produces pretty odd looking escape sequences (dash for slash?? etc). The systemd team made some odd choices down the road. This is one of them.
    – hookenz
    Aug 24, 2021 at 20:35
  • In my case, paths returned by systemd-escape did not work. Replacing spaces with \x20 and no quotes worked.
    – Dominik
    Nov 28, 2021 at 14:44
3

The obvious thing to do is to use double quotes.

ExecStart="/home/cobra/my service/start.sh"

You also should get rid of the start.sh script and move any necessary logic into the unit.

4
  • Putting quotes around it like you suggested makes the service fail completely: Failed to start myservice.service: Unit myservice.service failed to load: Invalid argument.
    – Cobra_Fast
    May 24, 2015 at 23:07
  • The underlying error message seems to be Executable path is not absolute, ignoring: "/home/cobra..." myserivce.service lacks ExecStart setting. Refusing.
    – Cobra_Fast
    May 24, 2015 at 23:19
  • Turns out quoting the executable path is supported since systemd version 218-147 (2014-12-19) and debian jessie is still sitting on 215-17. I just wrote the debian people a bugreport, we'll see what comes of it.
    – Cobra_Fast
    May 25, 2015 at 0:21
  • 1
    @Cobra_Fast Good luck with that. Of course I would never advise using Debian at all, but that's another discussion... May 25, 2015 at 0:22
1

For spaces in ExecStart, there is an open bug report.[1] The workaround is to use /usr/bin/env followed by the path in quotes. Example:

ExecStart=/usr/bin/env "/path/with spaces/executable"

The canonical —but not so nice— solution is to use systemd-escape.

systemd-escape --path "/path/with spaces/executable"

[1] https://github.com/systemd/systemd/issues/2132

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .