F45 Change Proposal: Use Systemd For Managing Per User Environment Variables [SelfContained]

Use Systemd For Managing Per User Environment Variables

Wiki

Announced

This is a proposed Change for Fedora Linux.
This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee.

Summary :open_book:

Rely on systemd’s systemd.environment-generator functionality for managing per-user environment variables (such as appending ~/local/.bin and ~/bin to an user’s $PATH) instead of individual shellrc scripts (~/.bashrc, ~/.zshrc etc).

Owner :open_book:

Detailed Description :open_book:

Currently, Fedora relies on shellrc scripts (~/.bashrc, ~/.zshrc files) for modifying an user’s environment variables.

An example of such a case is appending ~/.local/bin and ~/bin directories to $PATH

Such shellrc scripts have only been packaged for the bash and zsh shells. (rpm -ql /etc/skel/{.bashrc,.zshrc} returns packages bash and zsh)

However, Fedora Linux also offers several alternative shells such as fish, nushell (nu), xonsh, dash etc, for which shellrc scripts have not been packaged.

This leads to a situation where an user might change their login shell and be unable to directly launch scripts and programs stored in ~/.local/bin and ~/bin

systemd provides a mechanism for applying environment variables to all user processes via systemd.environment-generator.

Creating simple drop-in file(s) in the /etc/skel/.config/environment.d/ directory is a simpler and much cleaner way for both managing environment variables for an user and for mitigating the $PATH environment variable propagation issue for alternative shells.

Although out of scope for this specific proposal, the broader goal will be to ultimately move as much cruft possible out of shellrc scripts scattered across the filesystem at different places and /etc/profile into environment-generators

Feedback :open_book:

Will be updated later.

Benefit to Fedora :open_book:

This change simplifies per-user environment variable propagation and makes environment variable changes independant of an user’s default shell.

Scope :open_book:

  • Proposal owners:
    Modify the /etc/skel/.*rc files located in the bash and zsh packages, modifying them to either remove any environment variable modification parts or splitting those parts into separate subpackages.

Search for any other packages that also modify environemt variables by shellrc scripts.

  • Other developers:
    Coordinate with the respective package maintainers.
  • Release engineering: [Making sure you're not a bot! #Releng issue number]
    Most likely no.
  • Policies and guidelines: N/A (not needed for this Change)
  • Trademark approval: N/A (not needed for this Change)
  • Alignment with the Fedora Strategy:

Upgrade/compatibility impact :open_book:

None.

Early Testing (Optional) :open_book:

Do you require ‘QA Blueprint’ support? N

How To Test :open_book:

Will be added later.

User Experience :open_book:

Cleaner shellrc files will ease management for users.

Dependencies :open_book:

Will be updated later.

Contingency Plan :open_book:

  • Contingency mechanism: (What to do? Who will do it?)
    Revert the change. (not a System Wide Change)
  • Contingency deadline: Beta freeze (not a System Wide Change)
  • Blocks release? N/A (not a System Wide Change), Yes/No

Documentation :open_book:

N/A (not a System Wide Change)

Release Notes :open_book:

\nMoved per-user environment variable handling to systemd.environment-generator\n

Last edited by @alking 2026-03-10T16:54:13Z

Last edited by @alking 2026-03-10T16:54:13Z

How do you feel about the proposal as written?

  • Strongly in favor
  • In favor, with reservations
  • Neutral
  • Opposed, but could be convinced
  • Strongly opposed
0 voters

If you are in favor but have reservations, or are opposed but something could change your mind, please explain in a reply.

We want everyone to be heard, but many posts repeating the same thing actually makes that harder. If you have something new to say, please say it. If, instead, you find someone has already covered what you’d like to express, please simply give that post a :heart: instead of reiterating. You can even do this by email, by replying with the heart emoji or just “+1”. This will make long topics easier to follow.

Please note that this is an advisory “straw poll” meant to gauge sentiment. It isn’t a vote or a scientific survey. See About the Change Proposals category for more about the Change Process and moderation policy.

Please don’t. I have enough trouble with systemd “managing” things for me as it is; I do not want it to muck about with my .rc files in any way, shape, or form. There is a lot of accumulated knowledge and experience in those files that I have no desire to translate into some other form.

This change will only impact newly created user accounts or fresh installs.
Besides, you can still use .rc files like you do today, that functionality remains untouched.

This change is about how the default environment variables Fedora itself sets are handled.

For example, take the default .bashrc file in /etc/skel/.bashrc

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# User specific environment
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]; then
    PATH="$HOME/.local/bin:$HOME/bin:$PATH"
fi
export PATH

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
if [ -d ~/.bashrc.d ]; then
    for rc in ~/.bashrc.d/*; do
        if [ -f "$rc" ]; then
            . "$rc"
        fi
    done
fi
unset rc

It will just become

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
if [ -d ~/.bashrc.d ]; then
    for rc in ~/.bashrc.d/*; do
        if [ -f "$rc" ]; then
            . "$rc"
        fi
    done
fi
unset rc

The # User specific environment part will be handled by systemd.

No. IMO, user-specific environment for users (especially those that install alternative shells) should be handled by the user, not by systemd. Unless this provides a major benefit to those users which install alternative shells, I don’t see any good reason to complicate environment modifications harder for (relatively speaking) normal users.

Detailed response:

I see no situation where this is a major problem. A user who intentionally installs an alternative shell (especialy one which is non-POSIX, such as fish or nushell) should be able to figure out how to resolve this. A user who intentionally installs things to ~/.local/bin/ or ~/bin/ should be able to figure out how to resolve this. Additionally, this doesn’t resolve any of the other issues encountered in switching shells (completion functions, proper shell-specific environment setup, etc.), which would still have to be completed. So at best you’re slightly reducing the amount of work that a power user has to do.

Maybe, but to my knowledge no tools use it, and most users probably don’t know about it.

Not to be rude, but “move as much as possible out of well-known config files and into systemd” sounds like a terrible idea. Config files are well-known and work across distributions, systemd is less well-known and inherently not cross-distribution.

That’s worse, as it means the user’s environment is divided across more locations, not less.

Systemd mucks about enough as is with system configurations. Don’t inject it into the user configuration for a 5% benefit to power users that know what they’re doing.

1 Like

This is a relatively minor change, all things considered.
Which is the reason I don’t see any reason NOT to implement it.

It keeps existing user workflows preserved (as mentioned in F45 Change Proposal: Use Systemd For Managing Per User Environment Variables [SelfContained] - #4 by faeizmahrus ) while also providing a nice QoL bonus for everyone.

This change proposal is about environment variables Fedora ships OOTB, users are still free to pursue either approach.

This is reserved for a future proposal, the current proposal is relatively simple.

Adding ~/.local/bin and ~/bin to $PATH is implemented in both ~/.bashrc and ~/.zprofile separately so that users who prefer zsh don’t have to go and do that manually (and vice-versa)

I think having one .conf somewhere is better than reimplementing the same functionality twice (or be manually implemented by the user like you mentioned in your reply)

Al Stone wrote:

Please don’t. I have enough trouble with systemd “managing” things for
me as it is; I do not want it to muck about with my .rc files in any
way, shape, or form. There is a lot of accumulated knowledge and
experience in those files that I have no desire to translate into some
other form.

I’m a no for the same reason.

rob

There is a major problem: this won’t work in environments where systemd isn’t active. The existing setup works with interactive container environments, whereas this proposed one probably will not.

yeah this change breaks PATH in console and ssh. this is immediately a hard no.

Just a reminder for people to vote in the webpage versus just replying “For” or “Against”. Saying you are against but not voting may not get counted.

1 Like

I am all in favour of having this pattern removed.
I think that its an error to change things like PATH in pre-subprocess .bashrc.
It should have been in .bash_profile.

But if the solution does not work for ssh into a machine its not useable.

Correct me if I’m missing something - but when containers are instantiated, you can set the environment variables. So if you know you have a container with executables in ~/bin, then you could set your PATH environment variable when the container is first run?

Hi guys voted opposed, but could be convinced.

it seems to me that the logic ends here

systemd provides a mechanism for applying environment variables to all user processes via systemd.environment-generator.

but then, as to why that’s appropriate to impose onto the distribution for all members, the argument isn’t clear; it’s clear for example, no one is asking for it.

If I want to use a new component for the system, then I can choose to use it or not, that makes it interesting, having it forced upon us is entirely different. I read the proposal twice, and I’m sort of lying half-way out of bed with my head nearly upside down. Maybe I misinterpreted it.

edit: it also seems to be proposed… reading through the thread abit, that this proposal will change the distribution for everybody, and simultaneously it will change nothing at all. (which is why we couldn’t possibly be against it, or in other words, both arguments are made in favor of the proposal(they can’t both be true))

I don’t think that’s correct, and in my experience learning to use Linux+Systemd over many years, new features introduced from upstream are felt by us downstream, as typically, new enforced dependencies, that require everybody to change their behavior, and learn a new system, and that creates a lot of confusion and revulsion with these systems broadly.

(this is starting to read like a new, broadly impactful, forced dependency)

edit2:(hey im new here, but I just quickly read through several previous major proposals, and the sense I get, is that there is typically only ONE OPTION, presented to us, and we can either agree or disagree, and it would be much more interesting, to look at a variety of solutions for the various problems, ONE OPTION is limited, a variety of solutions, is dynamic, adaptable, cool, smart)

I’m not sure this is correct - I imagine the systemd environment generator would work both on the console and also in ssh sessions to the host?

Nice, this will also mean that setting the PATH is idempotent and will no longer result in PATH duplication from nested shells (assuming you have something like PATH=$PATH:$HOME/.local/bin)

Totally in favour conceptually, but interested in some details:

  1. what other variables will be provided?
  2. Also I guess conditional PATH would still be handled by the shell? can the generator handle this?

if [ -d “$HOME/.local/bin” ]; then

export PATH=“$PATH:$HOME/.local/bin”

fi

According to systemd.environment-generator(7) yes, but seems only system generator scripts are supported iiuc.

Not sure how users would override them though?

Is the proposal actually suggesting to use systemd environment generators or just static environment.d/ files? It might be good to clarify/correct that?

My impression is the latter, but then why mention the former?

I am aware of the issues, there are still edge cases (toolbox/distrobox, WSL etc).

This change is “minor“ in the sense that it modifies 4-5 lines in /etc/skel for ~/.bashrc and ~/.zprofile while putting a simple, one-line drop-in in either /etc/skel/.config/environment.d/ or in /usr/lib/environment.d/ (have to look into it and test)
I am currently exploring fallback options for such cases and also looking for blockers.

Although, it seems like this change might get blocked due to `pam_systemd` should call `pam_setenv` for user manager environment variables ¡ Issue #35228 ¡ systemd/systemd ¡ GitHub
The change can still probably be implemented, albeit via some hack-y measures which I would rather not take.
Let’s see what can be done in upstream systemd first.

systemd.environment-generator is the systemd generator that implements the static environment.d/ environment variable modification functionality.

no. console and ssh sessions aren’t children of the user’s systemd, so they don’t get affected by its env. this was tested by multiple users in the fedora matrix chat. we’d have to polyfill support for environment generators in the bashrc and zshrc, which is nontrivial and would have to be duplicated across other shells anyways so makes this proposal not fix the problem it proposes to fix.