Include `$HOME/bin` in `PATH` for a systemd unit file

I set my path to include $HOME/bin in my ~/.bash_profile. I would like my user systemd services to also have the same value of $PATH. How can I do that?

In my ~/.bash_profile after setting the path I am doing

systemctl --user import-environment PATH

And in the service file where I need this path, I add a delay like this so that there is time for the import-environment to have run:

ExecStartPre=sleep 7

But that doesn’t seem to work. Any thoughts what I could do?

I would just set the PATH in the systemd unit file.
Use the Environment=PATH=path:path:etc
See systemd.service for how to use env var in unit files.

I have tried this approach, but it was inconvenient for me because I use the same setup on multiple machines (basically it’s one git repo cloned on different machines). I couldn’t figure out how to use standard environment variables like $HOME or $PATH, e.g. in this case I would like something like this:

Environment=PATH=$HOME/bin:$PATH

(where $PATH is whatever is the default for systemd user unit files)

I’m using user unit files.

Strange, because this returns a value that includes $HOME/bin.

To give more info: the unit I’m having trouble with runs emacs --daemon. I have both Emacs from the Fedora repos, and a newer Emacs I compiled from source which is installed in /opt/emacs.

I have a common setup across multiple machines. So on machines where I want to use the newer Emacs, I drop a symlink in $HOME/bin. Then my configuration need not know the difference between machines. However this doesn’t work if I use

ExecStart=emacs --daemon

although it works nicely if I use the full path /opt/emacs/bin/emacs.

I’ll experiment a bit and report back.

You should create a user service:
systemd/User - ArchWiki

Or use the one provided in the package:

dnf -q repoquery -l emacs-common | grep -e [.]service$

I’m already using user unit files, and I don’t want to use the one provided by emacs-common because it doesn’t shutdown cleanly (unsaved files maybe lost).

1 Like

What if you just used bash as part of the exec start?
/usr/bin/bash -c “emacs --daemon”

1 Like

I recall reading somewhere that systemd does not use the PATH for
ExecStart/ExecStartPre/ExecStartPost/etc.
You must always use the full path.

1 Like

It looks like this on Fedora 39:

> systemd-path search-binaries-default
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
1 Like

Create ~/.config/environment.d/path.conf with the following contents:

PATH=$HOME/bin:$PATH

Verify:

$ systemctl --user daemon-reload && systemctl --user show-environment

See environment.d for more info.

It will set the PATH, but systemd will only look in

> systemd-path search-binaries-default
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

for the program. If you run the program like

ExecStart=sh -c 'programname'

the sh will use the PATH to locate programname.

1 Like