home-manager
home-manager copied to clipboard
bug: environment variables are unavailable in ZSH since #2708 was merged
Is there an existing issue for this?
- [X] I have searched the existing issues
Issue description
Context: https://github.com/nix-community/home-manager/commit/2116fe6b50a5118d56f1f443cccf024abee9de40#r67122011
Maintainer CC
No response
System information
So far, this occurs on Darwin only.
This is an issue for at least PROMPT on NixOS: https://github.com/nix-community/home-manager/pull/2708#issuecomment-1047520943
Maybe we should have an explicit setting for prompt init in home-manager to make it less fragile against stuff like this...
It does seem that all of my settings do get set, including the PROMPT, it just doesn't have an effect:
johnw@Vulcan> env | grep PROMPT ~
PROMPT=%m %~ $
PROMPT_DIRTRIM=2
RPROMPT=
johnw@Vulcan> echo $PROMPT ~
%B%(?..[%?] )%b%n@%U%m%u>
johnw@Vulcan> export PROMPT='%m %~ $ ' ~
Vulcan ~ $ ~
@jwiegley
As I posted in https://github.com/nix-community/home-manager/commit/2116fe6b50a5118d56f1f443cccf024abee9de40#r67162926 , I think the reason for your output is that:
- you export
PROMPTin your.zshenv, PS1orPROMPTis set in/etc/zshrcbut not exported,envonly prints exported variables.
I can reproduce your output:
$ setopt interactivecomments
$ export PROMPT="exported_prompt> " # set by your .zshenv
exported_prompt> PS1="not_exported_prompt> " # set in /etc/zshrc. PS1 and PROMPT are the same, they use PS1 IIRC
not_exported_prompt> env | grep PROMPT
PROMPT=exported_prompt>
not_exported_prompt> echo $PROMPT
not_exported_prompt>
not_exported_prompt> export PROMPT="exported_prompt> "
exported_prompt>
Can you post content related to PROMPT or PS1 in your /etc/zshrc and .zshrc to confirm my guess?
If my guess is true, then it's not a bug, it a wrong user config.
PROMPT should not be exported since different shells have different syntax for it and will set it during initialization.
Also, as I said before, PROMPT should be set in .zshrc to override what /etc/zshrc sets and doing so will fix your issue.
It does seem that all of my settings do get set, including the
PROMPT, it just doesn't have an effect:
@berbiche Seems like this issue is only about PROMPT, maybe the title should be changed to something like "PROMPT in ZSH doesn't take effect since #2708 was merged "
There is also my issue where some variables (e.g. EDITOR) are overridden by /etc/zprofile.
There is also my issue where some variables (e.g. EDITOR) are overridden by
/etc/zprofile.
Can you post your /etc/zprofile?
https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/shells/zsh/default.nix#L59 (which eventually sources set-environment, which contains lines like export EDITOR=nano.
I mean your actual /etc/zprofile. I cannot reproduce your issue because my /etc/zprofile doesn't contain these lines (https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/shells/zsh/default.nix#L59) and these lines are not sourced on my system.
Can you provide a way to reproduce your issue?
That is my actual /etc/zprofile (or rather, I don't have an /etc/zprofile at the root). I don't have programs.zsh.enable at the nixos level (because there should be no need to configure it at that level). That file sources /etc/profile, which contains
# /etc/profile: DO NOT EDIT -- this file has been generated automatically.
# This file is read for login shells.
# Only execute this file once per shell.
if [ -n "$__ETC_PROFILE_SOURCED" ]; then return; fi
__ETC_PROFILE_SOURCED=1
# Prevent this file from being sourced by interactive non-login child shells.
export __ETC_PROFILE_DONE=1
if [ -z "$__NIXOS_SET_ENVIRONMENT_DONE" ]; then
. /nix/store/qwazca3pvvr2pijvy8jciypj8yy7hx22-set-environment
fi
# Read system-wide modifications.
if test -f /etc/profile.local; then
. /etc/profile.local
fi
if [ -n "${BASH_VERSION:-}" ]; then
. /etc/bashrc
fi
Where /nix/store/qwazca3pvvr2pijvy8jciypj8yy7hx22-set-environment contains
# DO NOT EDIT -- this file has been generated automatically.
# Prevent this file from being sourced by child shells.
export __NIXOS_SET_ENVIRONMENT_DONE=1
export EDITOR="nano"
export GIO_EXTRA_MODULES="/nix/store/2anfhzjz6d4n5xx5k5bfc9png6bjxis6-dconf-0.40.0-lib/lib/gio/modules"
export GTK_PATH="$HOME/.nix-profile/lib/gtk-2.0:$HOME/.nix-profile/lib/gtk-3.0:/etc/profiles/per-user/$USER/lib/gtk-2.0:/etc/profiles/per-user/$USER/lib/gtk-3.0:/nix/var/nix/profiles/default/lib/gtk-2.0:/nix/var/nix/profiles/default/lib/gtk-3.0:/run/current-system/sw/lib/gtk-2.0:/run/current-system/sw/lib/gtk-3.0"
export GTK_USE_PORTAL="1"
export INFOPATH="$HOME/.nix-profile/info:$HOME/.nix-profile/share/info:/etc/profiles/per-user/$USER/info:/etc/profiles/per-user/$USER/share/info:/nix/var/nix/profiles/default/info:/nix/var/nix/profiles/default/share/info:/run/current-system/sw/info:/run/current-system/sw/share/info"
export KDEDIRS="$HOME/.nix-profile:/etc/profiles/per-user/$USER:/nix/var/nix/profiles/default:/run/current-system/sw"
export LANG="en_IE.UTF-8"
export LC_TIME="en_GB.UTF-8"
export LD_LIBRARY_PATH="/nix/store/7j2n3xsdnhzy2f0lyszxpsdpr9pb40xb-pipewire-0.3.45-jack/lib"
export LESSKEYIN_SYSTEM="/nix/store/l907b9hlvg710sx9q8zsdjanaw3nlmf1-lessconfig"
export LESSOPEN="|/nix/store/v86yp3qqpl0j4kvfkniik0ayn6a0aqjr-lesspipe-1.85/bin/lesspipe.sh %s"
export LIBEXEC_PATH="$HOME/.nix-profile/lib/libexec:/etc/profiles/per-user/$USER/lib/libexec:/nix/var/nix/profiles/default/lib/libexec:/run/current-system/sw/lib/libexec"
export LOCALE_ARCHIVE="/run/current-system/sw/lib/locale/locale-archive"
export MOZ_PLUGIN_PATH="$HOME/.nix-profile/lib/mozilla/plugins:/etc/profiles/per-user/$USER/lib/mozilla/plugins:/nix/var/nix/profiles/default/lib/mozilla/plugins:/run/current-system/sw/lib/mozilla/plugins"
export NIXPKGS_CONFIG="/etc/nix/nixpkgs-config.nix"
export NIX_PATH="/etc/channels"
export NO_AT_BRIDGE="1"
export PAGER="less"
export PATH="$HOME/.nix-profile/bin:/etc/profiles/per-user/$USER/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin"
export QTWEBKIT_PLUGIN_PATH="$HOME/.nix-profile/lib/mozilla/plugins/:/etc/profiles/per-user/$USER/lib/mozilla/plugins/:/nix/var/nix/profiles/default/lib/mozilla/plugins/:/run/current-system/sw/lib/mozilla/plugins/"
export QT_PLUGIN_PATH="$HOME/.nix-profile/lib/qt4/plugins:$HOME/.nix-profile/lib/kde4/plugins:/etc/profiles/per-user/$USER/lib/qt4/plugins:/etc/profiles/per-user/$USER/lib/kde4/plugins:/nix/var/nix/profiles/default/lib/qt4/plugins:/nix/var/nix/profiles/default/lib/kde4/plugins:/run/current-system/sw/lib/qt4/plugins:/run/current-system/sw/lib/kde4/plugins"
export SSH_ASKPASS=""
export TERMINFO_DIRS="$HOME/.nix-profile/share/terminfo:/etc/profiles/per-user/$USER/share/terminfo:/nix/var/nix/profiles/default/share/terminfo:/run/current-system/sw/share/terminfo"
export TZDIR="/etc/zoneinfo"
export XCURSOR_PATH="$HOME/.icons:$HOME/.local/share/icons:$HOME/.nix-profile/share/icons:$HOME/.nix-profile/share/pixmaps:/etc/profiles/per-user/$USER/share/icons:/etc/profiles/per-user/$USER/share/pixmaps:/nix/var/nix/profiles/default/share/icons:/nix/var/nix/profiles/default/share/pixmaps:/run/current-system/sw/share/icons:/run/current-system/sw/share/pixmaps"
export XDG_CONFIG_DIRS="/etc/xdg:$HOME/.nix-profile/etc/xdg:/etc/profiles/per-user/$USER/etc/xdg:/nix/var/nix/profiles/default/etc/xdg:/run/current-system/sw/etc/xdg"
export XDG_DATA_DIRS="/nix/store/3yiqbc66573m1m0z2jk1hl28ri2qciqj-desktops/share:$HOME/.nix-profile/share:/etc/profiles/per-user/$USER/share:/nix/var/nix/profiles/default/share:/run/current-system/sw/share"
export XDG_DESKTOP_PORTAL_DIR="/nix/store/acaj431c40is6y5vv65j4825sgk4m3pw-xdg-portals/share/xdg-desktop-portal/portals"
if [ -e "$HOME/.nix-defexpr/channels" ]; then
export NIX_PATH="$HOME/.nix-defexpr/channels${NIX_PATH:+:$NIX_PATH}"
fi
# Wrappers override other bin directories.
export PATH="/run/wrappers/bin:$PATH"
unset ASPELL_CONF
for i in /run/current-system/sw /nix/var/nix/profiles/default /etc/profiles/per-user/$USER $HOME/.nix-profile ; do
if [ -d "$i/lib/aspell" ]; then
export ASPELL_CONF="dict-dir $i/lib/aspell"
fi
done
export NIX_USER_PROFILE_DIR="/nix/var/nix/profiles/per-user/$USER"
export NIX_PROFILES="/run/current-system/sw /nix/var/nix/profiles/default /etc/profiles/per-user/$USER $HOME/.nix-profile"
# reset TERM with new TERMINFO available (if any)
export TERM=$TERM
I can reproduce your issue. The key to reproduce is to not use a graphic environment because display managers will source /etc/profile and /etc/profile will not be sourced again later so your issue will not appear in a graphic environment.
Additionally, I can confirm that your linked code will run if and only if it's a login shell.
I think setting the nixos option programs.zsh.enable to true is a reasonable workaround, in which case /etc/zprofile will be sourced instead of /etc/profile and /nix/store/hash-set-environment will be sourced in /etc/zshenv.
@chvp Sorry, I made a mistake in my last comment. I have corrected it.
I still think the proper way to fix your issue is to change the behavior of zsh from nixpkgs.
Yeah, I'm pretty sure I agree that this is something that should be fixed in nixpkgs. I did enable programs.zsh.enable as a workaround. (Something I did not realize is that the set-environment script is sourced in /etc/zshenv in that case, which is definitely the more proper zsh way to do things.)
I've also noticed that after this change, none of standard bindkey mappings works. For example, I used to have in my shell (without any modifications) the following:
"^E" end-of-line
"^F" forward-char
After the change I have:
"^E"-"^F" self-insert
@knl I don't think this commit cause your issue since it only move session variables.
Anyway, can you provide a minimal working example to reproduce your issue?
@knl I don't think this commit cause your issue since it only move session variables.
Anyway, can you provide a minimal working example to reproduce your issue?
I did a bisect, and this commit was the first one that broke the expected behavior. By bisect, I mean I re-deployed my home-manager configuration with different versions of home-manager, and then checking the output of bindkey in a newly opened shell. I'll try to provide the minimal working example in the next 24h. Also, I'll open a new issue, just not to pollute this one (unless it's ok to keep the whole discussion here)?
One thing that strikes me is that the relToDotDir ".zshenv" file is concatenated/merged ~three~ four times within the mkMerge list.
Considering order matters quite a bit when initializing a shell, I'm wondering if the additions from #2708 would be appended to the resulting file after the value of envExtra? In general, I find the mkMerge usage here to be somewhat less-than-explicit (but let's also leave room for my own lack of understanding here 😅).
https://github.com/nix-community/home-manager/blob/afe96e7433c513bf82375d41473c57d1f66b4e68/modules/programs/zsh.nix#L408-L410
https://github.com/nix-community/home-manager/blob/afe96e7433c513bf82375d41473c57d1f66b4e68/modules/programs/zsh.nix#L424-L429
https://github.com/nix-community/home-manager/blob/afe96e7433c513bf82375d41473c57d1f66b4e68/modules/programs/zsh.nix#L431-L434
https://github.com/nix-community/home-manager/blob/afe96e7433c513bf82375d41473c57d1f66b4e68/modules/programs/zsh.nix#L445-L456
In which order will these be applied to the resulting file?
Would the following change to the third section (and corresponding removal of the existing examples) potentially result in the expected behavior?
{
home.file."${relToDotDir ".zshenv"}".text = ''
${optionalString (cfg.dotDir != null) "ZDOTDIR=${zdotdir}"}
${optionalString (cfg.oh-my-zsh.enable) ''
ZSH="${pkgs.oh-my-zsh}/share/oh-my-zsh";
ZSH_CACHE_DIR="${config.xdg.cacheHome}/oh-my-zsh";
''}
# Environment variables
. "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
# Only source this once
if [[ -z "$__HM_ZSH_SESS_VARS_SOURCED" ]]; then
export __HM_ZSH_SESS_VARS_SOURCED=1
${envVarsStr}
fi
### Move the `envExtra` value here ###
${optionalString (cfg.envExtra != "") cfg.envExtra}
'';
}
Can confirm NixOS setting programs.zsh.enable = true; works for getting my EDITOR setting back on NixOS.
@montchr
LGTM. I don't use oh-my-zsh though. Not sure about that part.
I think PR is welcome.
I don't use oh-my-zsh though. Not sure about that part.
@jian-lin Same, though based on the variables it touches, it seemed like the sort of low-level change that belongs close to the top of the file.
I opened #2787, which also adds a programs.zsh.envExtraFirst option along the lines of programs.zsh.initExtraFirst.
@knl @jwiegley et al. if you're open to testing #2787, I'm curious to know whether it addresses the issues that prompted this ticket.
For what it's worth, I tried the change from #2787 in my own repo https://github.com/akanter/nix-config in https://github.com/akanter/nix-config/blob/ee86b34c24f524ab158f48ff7e11e1e4b579164b/darwin-configuration.nix and my $EDITOR was still broken. The only way I was able to fix this was to revert #2708.
Some advice on debugging:
echo $__HM_ZSH_SESS_VARS_SOURCEDto see if.zshenvis sourced. Let's assume it is sourced.unset __HM_ZSH_SESS_VARS_SOURCED && zsh -c 'echo $EDITOR'to see ifEDITORis overridden in.zshenvunset __HM_ZSH_SESS_VARS_SOURCED && zsh -i -c 'echo $EDITOR'to see ifEDITORis overridden by/etc/zshrcor.zshrcunset __HM_ZSH_SESS_VARS_SOURCED && zsh -l -c 'echo $EDITOR'to see ifEDITORis overridden by/etc/zprofileor.zprofile.
Using montchr/home-manager/tree/zsh-env-section-order
>echo $__HM_ZSH_SESS_VARS_SOURCED
1
>unset __HM_ZSH_SESS_VARS_SOURCED && zsh -c 'echo $EDITOR'
nano
>unset __HM_ZSH_SESS_VARS_SOURCED && zsh -i -c 'echo $EDITOR'
nano
>unset __HM_ZSH_SESS_VARS_SOURCED && zsh -l -c 'echo $EDITOR'
nano
>cat ~/.zshenv
# Environment variables
. "/Users/ak/.nix-profile/etc/profile.d/hm-session-vars.sh"
# Only source this once
if [[ -z "$__HM_ZSH_SESS_VARS_SOURCED" ]]; then
export __HM_ZSH_SESS_VARS_SOURCED=1
fi
#
# Defines environment variables.
#
# Authors:
# Sorin Ionescu <[email protected]>
#
# Ensure that a non-login, non-interactive shell has a defined environment.
if [[ ( "$SHLVL" -eq 1 && ! -o LOGIN ) && -s "${ZDOTDIR:-$HOME}/.zprofile" ]]; then
source "${ZDOTDIR:-$HOME}/.zprofile"
fi
Not sure what's going on but I hope this can assist you!
My bad. I misread. Actually, you set EDITOR in home.sessionVariables instead of programs.zsh.sessionVariables. So the guard variable __HM_ZSH_SESS_VARS_SOURCED should be changed to __HM_SESS_VARS_SOURCED.
#
# Defines environment variables.
#
# Authors:
# Sorin Ionescu <[email protected]>
#
# Ensure that a non-login, non-interactive shell has a defined environment.
if [[ ( "$SHLVL" -eq 1 && ! -o LOGIN ) && -s "${ZDOTDIR:-$HOME}/.zprofile" ]]; then
source "${ZDOTDIR:-$HOME}/.zprofile"
fi
But I cannot find this in your home manager config. That should not exist since your .zshenv is generated by home manager. Also, it is not needed as it is taken care of by the zsh module.
Could you remove that and redo the test with __HM_SESS_VARS_SOURCED?
Ah, that comes from zsh-prezto.
Ah, I think I find the cause of your issue: zsh-prezto also sets some variables like EDITOR in .zprofile, which overridden the ones we set in .zshenv.
I skim through prezto's zsh settings and think that prezto can be improved.
@akanter For your issue, prezto should set variables like EDTIOR in .zprofile only if they are not set. Maybe you can make a PR for prezto?
Not sure if there are more incompatibilities between our zsh module and prezto.
https://github.com/sorin-ionescu/prezto/pull/1992 fixed this problem, just needs an update.
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 you are the original author of the issue
- 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 not the original author of the 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.
Memorandum on closing issues
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.
I am having similar issues but I am not using prezto. If I add:
programs.zsh = {
enable = true;
sessionVariables = {
ASD = "asdasd";
};
...
};
And then edit /etc/profiles/per-user/dbarroso/etc/profile.d/hm-session-vars.sh and change it to:
# Only source this once.
echo 1 # <-------
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi
echo 2 # <------
export __HM_SESS_VARS_SOURCED=1
export EDITOR="nvim":w
When I open a new shell I see 1 twice but never 2 so I am not sure who/where that var is being set but the contents of .zshenv are never fully loaded due to the the gate:
. "/etc/profiles/per-user/dbarroso/etc/profile.d/hm-session-vars.sh"
# Only source this once
if [[ -z "$__HM_ZSH_SESS_VARS_SOURCED" ]]; then
export __HM_ZSH_SESS_VARS_SOURCED=1
export ASD="asdasd"
fi
Disregard, in my case I figured the issue was due to the fact I am using nix-darwin + home-manager and I had zsh enabled in both in which case there are bad interactions in there.
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 you are the original author of the issue
- 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 not the original author of the 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.
Memorandum on closing issues
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.
FYI, I created a pr to let you disable the system-level programs.zsh.enable option. https://github.com/NixOS/nixpkgs/pull/217205