Using a user's .bashrc in a systemd service
If you must...
Instead of trying to generate an EnvironmentFile, have a shell execute your startup scripts and then execute your command. This avoids steps that can introduce a mismatch (as between how env
stores your environment, and how the systemd EnvironmentFile
option loads it).
To source your target user's startup scripts:
[Service]Type=simpleUser=userGroup=userExecStart=/bin/bash -l -c 'exec "$@"' _ your-command arg1 arg2 ...
To source an arbitrary file:
Here, instead of using bash -l
to run a login shell, we explicitly source $0
, and pass /home/user/.bashrc
in that position.
[Service]Type=simpleUser=userGroup=userExecStart=/bin/bash -c '. "$0" && exec "$@"' /home/user/.bashrc your-command arg1 arg2 ...
But Don't. Really.
.bashrc
files are generally intended for setting up interactive environments. This means that their settings are often not appropriate for services.- Building a separate
EnvironmentFile
that you hand-audit for your service means you know exactly what the service is running with, and can configure it separately from the interactive environment. If you've hand-audited that EnvironmentFile to have the same meaning when executed by a shell, you could also runset -a; source /path/to/your-environment-file; set +a
in your.bashrc
to pull its environment variables in. - From a security perspective, it's generally unwise to let a service modify any executable code it runs -- providing such permissions means that an attacker who has breached a service can make their breach persistent even without any secondary privilege escalation attacks. Using an
EnvironmentFile
in a non-user-writable location like/etc/conf.d
is thus safer than a dotfile under that user's home directory.