Common Issue: accessing binaries

Coming from other systems, you may be used to locating binaries like /bin/bash.

On NixOS, the currently used binaries are in various places of the nix store

~ ❯❯❯ whereis bash
bash: /nix/store/ggl4fqsvvlyf1y3rl6mk72nf0dc8c8hr-system-path/bin/bash

Instead you can use this directory, where the binaries are linked to. Note that there is no guarantee that the binaries are there.

/run/current-system/sw/bin/

It should also be in your PATH, so you can run the binaries directly, also in .desktop files and scripts.

Read below on options how to use nix instead

1 Like

“their path always changes” can be better thought of as “there are multiple paths”.

And those paths–those store paths–are obtained via usage of the Nix language. For example, lib.getExe pkgs.gnugrep.

I don’t remember ever explicitly addressing /run/current-system/sw/bin/. When an executable is in your path it hopefully reached there via idiomatic usage of Nix code such as the above or the NixOS environment.systemPackages or the Home Manager home.packages options or similar.

For use in a script, you have for example the runtimeInputs of pkgs.writeShellApplication or an inline lib.getExe or lib.getExe'.

Such usages attempt to guarantee the existence of the expected executable at a certain Nixpkgs revision and configuration in the store. Referring to /run/current-system/sw/bin provides no such guarantees.

4 Likes

What if you want to find binaries without using Nix? Like in a bash script?

Normally binaries should be in your PATH so this is a prerry rare situation I guess

1 Like

Right: the pattern is to link store paths to well known locations or add store paths to well known environment variables. A big truth though of why you don’t want to reference is /run/current-system/sw/bin/ imo is that you aren’t actually creating a stable reference under gc. To wit: lets say I write a script that depends on git and to it in the following way pkgs.writeShellScriptBin "rev-parse" "/run/current-system/sw/bin/git rev-parse HEAD". There is no guarantee that git isn’t going to be removed from environment.systemPackages. Alternatively pkgs.writeShellScriptBin "rev-parse" "${lib.getExe pkgs.git} rev-parse HEAD" is a script that doesn’t care about the globally installed packages, it guarantees its own dependencies are available. Same for desktop files: always interpolate the derivation into the file, now your desktop files install the software they depend on to be valid if they themselves are referenced. This is imo the true zen of nix. Say no to plop!

1 Like

Use nix to write or at least package the script, because that’s the only way to guarantee that the dependent binaries exist.

2 Likes

Wow this is totally new to me, I will learn it for sure :wink:

1 Like