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?

Cobra_Fast
  • 630
  • 2
  • 7
  • 22
  • Have you tried backslash space ("\ ") like the shell? – hookenz May 24 '15 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 '15 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 '15 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 04 '15 at 02:17
  • Did you figure out how to get WorkingDirectory to work with spaces? Nothing is working for me. – leetNightshade Jul 16 '20 at 02:08

3 Answers3

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 -

Geoffrey
  • 63
  • 2
  • 14
hookenz
  • 14,132
  • 22
  • 86
  • 142
  • 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 '21 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 '21 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 '21 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.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • 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 '15 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 '15 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 '15 at 00:21
  • 1
    @Cobra_Fast Good luck with that. Of course I would never advise using Debian at all, but that's another discussion... – Michael Hampton May 25 '15 at 00: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

goetzc
  • 113
  • 4