kolam
kolam

Reputation: 741

Systemd user service exec command not in path

In my NixOS configuration.nix, I created the following service :

systemd.user.services.xcape-daemon = {
  description = "Xcape Daemon";
  after=[ "graphical.target" ];

  serviceConfig = {
    Type = "forking";
    ExecStart = ''${pkgs.xcape} -e "Hyper-L=Tab;Hyper_R=less"'';
    # ExecStop = "pkill xcape"; #pkill not found in path
    Restart = "on-failure";
  };

  wantedBy = [ "default.target" ];
};

systemd.user.services.xcape-daemon.enable = true;

However, I get the following error when checking the status of the service:

Executable "xcape" not found in path "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"

Problem is that this is not my actual $PATH.

My $PATH is : /home/user/bin /run/wrappers/bin /home/user/.nix-profile/bin /etc/profiles/per-user/user/bin /nix/var/nix/profiles/default/bin /run/current-system/sw/bin

Upvotes: 3

Views: 2880

Answers (1)

Frantisek Sumsal
Frantisek Sumsal

Reputation: 126

This is actually expected, as systemd uses a fixed value for $PATH determined at compilation time (to determine whether you're on a split-usr distro or not).

Quote from the systemd.exec(5) man page:

 $PATH
       Colon-separated list of directories to use when launching executables.  systemd uses a fixed value of "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin" in the system manager. When compiled for systems with "unmerged
       /usr" (/bin is not a symlink to /usr/bin), ":/sbin:/bin" is appended. In case of the the user manager, each bin/ and sbin/ pair is switched, so that programs from /usr/bin have higher priority than programs from /usr/sbin,
       etc. It is recommended to not rely on this in any way, and have only one program with a given name in $PATH.

You have several options how to solve this:

  1. Use a full path to the xcape binary: ExecStart=/full/path/to/bin/xcape -e ...

  2. Define your own $PATH by using either:

    a. Environment="PATH=/bin:/sbin:/nix/var/nix/profiles/default/bin:..."

    b. EnvironmentFile=/etc/myservice/myenvfile where /etc/myservice/myenvfile contains definitions of environment variables (see systemd.exec(5) for documentation to both directives)

Upvotes: 2

Related Questions