Systemd 用户服务执行命令不在路径中

Systemd user service exec command not in path

在我的 NixOS configuration.nix 中,我创建了以下服务:

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;

但是,我在检查服务状态时收到以下错误:

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

问题是这不是我实际的 $PATH。

我的 $PATH 是:/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

这实际上是预期的,因为 systemd 使用编译时确定的 fixed$PATH(以确定您是否使用 split-usr 发行版或不是)。

引自 systemd.exec(5) 手册页:

 $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.

您有几种解决方法:

  1. 使用 xcape 二进制文件的完整路径:ExecStart=/full/path/to/bin/xcape -e ...

  2. 定义您自己的 $PATH 使用以下任一方法:

    一个。 Environment="PATH=/bin:/sbin:/nix/var/nix/profiles/default/bin:..."

    b。 EnvironmentFile=/etc/myservice/myenvfile 其中 /etc/myservice/myenvfile 包含环境变量的定义(有关这两个指令的文档,请参阅 systemd.exec(5)