How do I add ~/bin to PATH for a systemd service?
You could hardcode the PATH
in the systemd service:
[Service]
Environment=PATH=/home/someUser/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
More flexible would be PAM. It's awfully roundabout compared to simply using bash -c '....'
, but you can do this with PAM.
Create a new PAM configuration in /etc/pam.d
(say /etc/pam.d/foo
) and add:
session required pam_env.so user_envfile=some-file user_readenv=1
And in /home/someUser/some-file
, add:
PATH DEFAULT=/home/someUser/bin:${PATH}
Of course, you can adjust the some-file
name to something more sensible, but the path in user_envfile
has to be relative to the user's home directory (the user that you set in User=
in the service).
Then in the service file, in the [Service]
section, add (foo
being the file in /etc/pam.d
created earlier):
PAMName=foo
Now, when you start the service (after reloading, etc.), the session
modules in /etc/pam.d/foo
will be run, which in this case is just pam_env
. pam_env
will load environment variables from /etc/environment
, subject to constraints in /etc/security/pam_env.conf
, and then the user environment from ~/some-file
. Since PATH
is set to a default value in /etc/environment
, the user environment prepends to this default value.
Here, the default value of user_envfile
is .pam_environment
, which is also read by the PAM configuration of other things like SSH or LightDM login, etc. I used a different file here in case you don't want to affect these things. You could remove the user_envfile=...
and use the default ~/.pam_environment
. you could also just use an existing PAM configuration in /etc/pam.d
which has user_readenv=1
, but other PAM modules may cause unwanted side effects.
It seems terribly hackish, but prepending a $PATH
update seems to work.
I'm on the lookout for side-effects however . . .
Example:
ExecStart=/bin/bash -c "PATH=/home/someUser/bin:$PATH exec /usr/bin/php /some/path/to/a/script.php"
In a service I was setting up (Apache Airflow) I had an Environment File set.
In my /etc/systemd/system/airflow
file, I had this line:
[Service]
EnvironmentFile=/etc/default/airflow
Opening this environment file, I added the line I needed, in my case:
SCHEDULER_RUNS=5
PATH=/opt/anaconda3/bin:$PATH
Add whatever paths to the executables you need to be able to be reached by the service here and you should be ok. Worked well for me.