nix-installer icon indicating copy to clipboard operation
nix-installer copied to clipboard

Sourcing Nix in /etc/zshenv on MacOs breaks $PATH when SSH

Open nickkadutskyi opened this issue 4 months ago • 0 comments

I noticed that ConfigureRemoteBuilding adds code into /etc/zshenv to source Nix when SSH into a machine.

The problem is that after /etc/zshenv Mac runs /etc/zprofile which runs /usr/libexec/path_helper which changes the order of items in $PATH. After this Nix is sourced again in /etc/zshrc but in this case nix-daemon.sh doesn't do anything since __ETC_PROFILE_NIX_SOURCED is already set to true.

This results into a situation where /usr/bin precedes path/to/home/.nix-profile/bin:/nix/var/nix/profiles/default/bin in $PATH which overrides Nix packages with default ones. E.g. after running nix profile install git you still will be using /usr/bin/git.

It's working fine when I am not SSHing into my machine and work directly since sourcing happens in /etc/zshrc (after /usr/libexec/path_helper reordering)

My understanding is that /etc/zshenv is the only .z* file sourced when run in non-interactive mode thus the goal was to handle non-interactive shell case. If that's the case should it prevent sourcing Nix in /etc/zshrc in interactive shells?

Instead of:

if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ] && [ -n "${SSH_CONNECTION}" ] && [ "${SHLVL}" -eq 1 ]; then
    . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi

it should be something like this:

if [[ $- != *i* ]] && [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ] && [ -n "${SSH_CONNECTION}" ] && [ "${SHLVL}" -eq 1 ]; then
    . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi

This won't solved PATH override in non-interactive shell but it will solve the issue when SSHing into machine in interactive shell.

nickkadutskyi avatar Apr 15 '24 07:04 nickkadutskyi