Open sagikazarmark opened 2 years ago
While it works with most session variables, it breaks home.sessionPath that modifies PATH. It breaks, because zshenv is loaded first and subsequent PATH modifications (like Nix loading) override variables set in zshenv.
I still don't understand why it breaks home.sessionPath
. Can you elaborate on that?
Also, what do you mean by "Nix loading"?
E.g. running "PATH=/custom/path gdb program" sources this file (when gdb runs the program via $SHELL), so you want to be sure not to override a custom environment in such cases.
The change in #2708 doesn't have this issue because setting session variables is guarded by a variable to not run more than once.
I still don't understand why it breaks
home.sessionPath
. Can you elaborate on that?Also, what do you mean by "Nix loading"?
nix.sh
is sourced after zshenv and it overrides PATH. Since session vars are only sourced once, nix.sh
's override stays in effect.
The change in #2708 doesn't have this issue because setting session variables is guarded by a variable to not run more than once.
That's exactly the problem: they are sourced too early and only once. Path modifications are not supposed to be in zshenv.
nix.sh is sourced after zshenv and it overrides PATH. Since session vars are only sourced once, nix.sh's override stays in effect.
So you use nix on a foreign system given that you say nix.sh
, right? I have one machine running gentoo with nix. Its nix.sh
sets PATH
like this: export PATH="$NIX_LINK/bin:$PATH"
. Is it what you mean by override? If so, I still don't understand why home.sessionPath
is broken since it remains in PATH
after nix.sh
's change.
That's exactly the problem: they are sourced too early and only once.
No, they are two different situation.
The example .zshenv you quote says .zshenv should not contain PATH
setting because if so your custom PATH
(PATH=/custom/path gdb program) will be overridden by the PATH set in .zshenv. Home-manager's zsh module doesn't have this issue, i.e. your custom PATH
will not be overridden by the PATH
set in .zshenv.
What you say is the contrary: custom PATH
is not overridden by the PATH
in .zshenv. I am confused since what you want and what the example .zshenv you quote tries to avoid is the same thing.
Path modifications are not supposed to be in zshenv.
Please show us what exactly your issue is and provide a minimal reproducible environment.
I use both NixOS and macOS. Haven't tested it on macOS yet, but on NixOS sessionPath is missing from the PATH after upgrading to 22.05.
It does contain the nix profile PATH though, so my only explanation is that something overrides the PATH after zshenv is loaded for the first time. I went through my own scripts and nothing sets the PATH, I only use sessionPath and the ZSH module.
I'll try to reproduce it in an isolated environment later.
Steps to reproduce:
configuration.nix
:
# ...
users.users.mark = {
hashedPassword = "...";
description = "User";
isNormalUser = true;
shell = pkgs.zsh;
extraGroups = [
"wheel"
"networkmanager"
"audio"
"video"
"docker"
"input"
];
openssh.authorizedKeys.keys = [
"..."
];
};
home.nix
:
# ...
home.sessionPath = ["$HOME/.local/bin"];
programs.zsh = {
enable = true;
sessionVariables = { FOO = "bar"; };
};
echo $PATH
/run/wrappers/bin:/home/mark/.nix-profile/bin:/etc/profiles/per-user/mark/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin
echo $FOO
bar
The set-environment script sourced in /etc/profile
contains the following line:
export PATH="$HOME/.nix-profile/bin:/etc/profiles/per-user/$USER/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin"
It completely overrides PATH. This script is sourced after zshenv is loaded for the first time. The session variables script is sourced only once and it's sourced before profile (in zshenv).
Do you have system leval programs.zsh.enable
enabled?
I don't. The problem is reproducible with the above minimal config.
Please enable that and set-environment will be sourced in /etc/zshenv, which is the right way for zsh.
see https://github.com/nix-community/home-manager/issues/2751#issuecomment-1048682643
Thanks, I'll try that later. I wonder if that's going to work on Mac though.
Any ideas how we can make it easier for users to figure out the ZSH module depends on a global setting?
I think a mention in the manual and release note will help. Will you make a PR for that?
I wonder if that's going to work on Mac though
As long as mac's /etc/{zprofile,zshrc}
are sane, i.e. not removing items from PATH
, it should be ok.
Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.
* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.
Is there an existing issue for this?
Issue description
2708 moved session variable loading from
.zshrc
to.zshenv
.While it works with most session variables, it breaks
home.sessionPath
that modifiesPATH
.It breaks, because zshenv is loaded first and subsequent PATH modifications (like Nix loading) override variables set in zshenv.
Prior to #2708 I submitted #2445 assessing the situation. In that (based on #183) I concluded that .zshenv is not the best place for session variables. Quoting the example .zshenv file:
Quoting why it was still added to
.zshenv
from #2708:Based on the available information, I believe
.zshenv
is not the right place for session variables by default. I understand that it's problematic for some graphical sessions, but the current solution still goes against how ZSH startup scripts are supposed to be used and requires workarounds for "normal" use cases.I propose moving session variables to zprofile instead of zshenv. Anyone in need of loading them in zshenv as well can workaround the issue (or we can introduce a variable if that's absolutely necessary).
I'd also like to point out that bash also uses the equivalent of zprofile at the moment.
Temporary workaround:
Maintainer CC
cc @jian-lin
System information