Worth pointing out that with Nix/NixOS this problem doesn't exist.

The problem in other distros is that if you prefix PATH so that it contains your executable "foo", and then run a program that invokes "foo" from PATH and expects it to do something else, the program breaks.

With Nix, this problem does not exist because all installed programs invoke all other programs not via PATH but via full absolute paths starting with /nix/store/HASH...

The "solution" of only ever using full absolute paths works on any unix system, doesn't it?

Yes with a but:

NixOS simultaneously smooths the path to using absolute paths while putting some (admittedly minor) speed-bumps in the way when avoiding them. If you package something up that uses relative paths it will probably break for someone else relatively quickly.

What that means is that you end up with a system in which absolute paths are used almost everywhere.

This is why the killer feature of NixOS isn't that you can configure things from a central place; RedHat had a tool to do that at least 25 years ago; it's that since most of /etc/ is read-only, you must configure everything from a central place, which has two important effects:

1. The tool for configuring things in a central place can be much simplified since it doesn't have to worry about people changing things out from under it

2. Any time someone runs into something that is painful with the tool for configuring things in a central place, they have to improve the tool (or abandon NixOS).

So if I want to use grep in a small script, do I have to write:

/nix/store/grep-hash -flags files | /nix/store/head-hash

instead of: "grep -flags files | head"?

If it's a one off, you just use something like "nix shell" to add it to your path for running the script.

For non one-off sorts of things, you would substitute in the nix expression "${gnugrep}/bin/grep" the "${gnugrep}" will expand to "/nix/store/grep-hash" and also make a dependency on the gnugrep package, so that the grep install won't get garbage-collected as long as your package is still around.

Here's an example[1] from a package expression for e-mail client I use, which will shell out to base64 and file. Upstream relies on these two programs being in $PATH, but this replaces the string used for shelling out with the absolute path in the nix store.

For shell scripts, I'll just do something like this near the top:

   GREP="${GNU_GREP:-$(command -v grep)}"
Then I use "$GREP" in the script itself, and develop with grep in my path, but it's trivial to prepend all of my dependencies when I bundle it up for nix.

1: https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/no...

    [user@nixos:~]$ which grep
    /run/current-system/sw/bin/grep

    [user@nixos:~]$ ls -l /run/current-system/sw/bin/grep
    lrwxrwxrwx 1 root root 65 Jan  1  1970 /run/current-system/sw/bin/grep -> /nix/store/737jwbhw8ji13x9s88z3wpp8pxaqla92-gnugrep-3.12/bin/grep
Basically, it is still in your environment, so I don't see how he can claim that this problem doesn't exist in Nix, unless you use flakes like a proper Nix afficionado.

Yes, the original comment that this problem doesn't exist in Nix is wrong for a typical user environment.

It does contain the issue a bit though:

I'm running isync in a systemd service, yet the program "mbsync" is not in my path. I have several services installed, yet their programs aren't in my path. My e-mail client shells out to "file" for mime-type verification, yet "file" is not in my path.

Run "compgen -c |wc -l" to get a list of commands; its over 7000 on my Ubuntu system and right around 2000 on my NixOS system.

As an aside, the packages that put the most executables in my path are probably going to be in the path for most NixOS installs (231 just for coreutils+util-linux):

     27 /nix/store/csxa6mi2mpjl9vqxbv2j0bha6sz6nbjw-cups-2.4.14
     31 /nix/store/334afxah19b3hr6ll93pfxlcyhhh2vws-pipewire-1.4.9
     31 /nix/store/h2jsb5i4yfblr2f3ac2c7zpmlmj7zjym-perl-5.40.0
     33 /nix/store/914x32c982bs3i1998yxvkg9svm3ycr5-shadow-4.18.0
     33 /nix/store/a6s3hzj3b2z6rsyfkjyxwn265iyfl2gn-mtools-4.0.49
     33 /nix/store/jky7jszaci5n7g426wf6nsg5dmik9nfw-kbd-2.9.0
     37 /nix/store/2v1l6mqz0d7mfpp4ksw2048v3g0a1a19-hplip-3.25.2
     45 /nix/store/90wlc37ljr6rpy2lan46bp0gq19vbgl5-iptables-1.8.11
     48 /nix/store/1byhxs7b28grh8s15jc2dvs2zg36swjb-lvm2-2.03.35-bin
     61 /nix/store/9xwxjkrwxjsvc5gs1l0syr4wbfvvvvcn-bluez-5.84
     64 /nix/store/zf8qy81dsw1vqwgh9p9n2h40s1k0g2l1-systemd-258.2
     72 /nix/store/1igrj9w84w7s3r80l3nkxcqwd84sw9mz-qemu-10.1.2
    106 /nix/store/v4q3154vdc83fxsal9syg9yppshdljyk-coreutils-full-9.8
    125 /nix/store/3c6r8gh8zrqw8xmncmlj9vivz9rz6r30-util-linux-2.41.2-bin

True enough, but in my experience it's not really much of a problem because if I'm not doing Nix, then I'm doing containers which are widely available.

What can be a problem is muscle memory, when you expect it to autocomplete one way and it doesn't because something you want now shares first two or three letters with something else in your path. That's where FIGNORE comes in.