Using `nix run` with several packages

I’m using Nix to install older Python versions on Debian and previously had wrapper scripts such as the following for python3.8:

exec nix-shell -p glibLocales python38 --run "$(printf '%q' python3.8 "$@")"

As you can see, this uses nix-shell to create an environment with two packages and executes the python3.8 command with any additional command-line parameters therein. Unfortunately, this doesn’t really go well with regularily running nix-store --gc and there does not appear to be any decent way of preventing these Nix packages as well as all their dependencies from nixpkgs from being garbage-collected.

After researching the issue a bit, it turns out that instead using nix run works and makes for a simpler script:

exec nix run 'nixpkgs#python38' -- "$@"

And that using nix build 'nixpkgs#python38' --out-link /nix/var/nix/gcroots/per-user/${USER}/python38 everything used by the above is nicely pinned and not removed anymore when running nix-store --gc.

However this makes me wonder how one would add the additional glibcLocales package to the environment created by nix run? I can’t exactly remember what that was for, but I do recall there having been issues when its missing.

I think for that you need to use nix shell, so something like:

nix shell nixpkgs#python38 nixpkgs#glibLocales --command python38 $@

1 Like

glibcLocales relies on setup hook to set the LOCALE_ARCHIVE environment variable. Unlike nix-shell, nix shell or other new command will not run setup hooks as that is too much Nixpkgs-specific behaviour. To be precise, nix-shell created a derivation using a helper from Nixpkgs – with new commands, you will need to create it explicitly using something like the following:

nix develop --impure --expr 'let pkgs = import (builtins.getFlake "nixpkgs/nixos-unstable") {}; in pkgs.mkShell { buildInputs = with pkgs; [ python3 glibcLocales ]; }'

See Qt development environment on a flake system - #5 by jtojnar for more details about creating shells this way.