Skip to content

PATH variable keeps growing in nested shells #11

@charego

Description

@charego

Thank you for this plugin.

I've just noticed that in nested shells, the PATH variable continues to grow.

> set --show PATH | grep nix
$PATH[6]: |/Users/charego/.nix-profile/bin|
$PATH[7]: |/nix/var/nix/profiles/default/bin|

> exec fish
> set --show PATH | grep nix
$PATH[1]: |/Users/charego/.nix-profile/bin|
$PATH[2]: |/nix/var/nix/profiles/default/bin|
$PATH[14]: |/Users/charego/.nix-profile/bin|
$PATH[15]: |/nix/var/nix/profiles/default/bin|

> exec fish
> set --show PATH | grep nix
$PATH[1]: |/Users/charego/.nix-profile/bin|
$PATH[2]: |/nix/var/nix/profiles/default/bin|
$PATH[9]: |/Users/charego/.nix-profile/bin|
$PATH[10]: |/nix/var/nix/profiles/default/bin|
$PATH[16]: |/Users/charego/.nix-profile/bin|
$PATH[17]: |/nix/var/nix/profiles/default/bin|

I'm not sure if this should be considered a bug with nix-env.fish or with the script that nix-env.fish sources and replays. In my case, I'm running a multi-user install on MacOS and nix-env.fish is sourcing the nix-daemon.sh script.

Here is the relevant snippet from this plugin:

set -l nix_profile_path /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
...
# Source the nix setup script
# We're going to run the regular Nix profile under bash and then print out a few variables
for line in (command env -u BASH_ENV bash -c '. "$0"; for name in PATH "${!NIX_@}"; do printf "%s=%s\0" "$name" "${!name}"; done' $nix_profile_path | string split0)
  set -xg (string split -m 1 = $line)
end

Here is the relevant snippet from nix-daemon.sh:

# Only execute this file once per shell.
if [ -n "${__ETC_PROFILE_NIX_SOURCED:-}" ]; then return; fi
__ETC_PROFILE_NIX_SOURCED=1

export NIX_PROFILES="/nix/var/nix/profiles/default $HOME/.nix-profile"
...
export PATH="$HOME/.nix-profile/bin:/nix/var/nix/profiles/default/bin:$PATH"

I'm able to "fix" the problem by updating nix-daemon.sh to check for duplicates:

# Prepend profile binaries to PATH if not already present.
for i in $NIX_PROFILES; do
  if [ -d "$i/bin" ] && [[ ":$PATH:" != *":$i/bin:"* ]]; then
    export PATH="$i/bin${PATH:+":$PATH"}"
  fi
done

But notice the script already has its own guard at the top, which doesn't work for us. So should this be guarded against by nix-env.fish, or is it something we need to push upstream? Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions