10

How can I figure out which nixpgs-package provides a given file/command, that may not be installed on the system?

Other package managers offer this functionality as follows:

Does nix have a similar feature?

Context: I was trying to figure out which package provides grep, before realizing it was provided by the gnugrep package (who would have thought?). I am looking for a systematic way to answer questions like these, as to avoid the guessing game next time.

Things I have tried:

4
  • The Nix ecosystem has a programming language and various devops tools which clearly belong on this site, so many Nix-related questions end up on stackoverflow. Having distinct sites for some categories of Nix-related questions is unintuitive. I guess mods must be tired of hearing those kinds of complaints. :( Aug 3, 2021 at 21:51
  • @RobertHensing, ...one could similarly argue that because writing rpm spec files are programming, questions about how to use rpm -q are also programming -- except they aren't. There's a clear delineation -- as stackoverflow.com/help/on-topic puts it -- around questions that are "unique to software development". Aug 3, 2021 at 22:21
  • That's only one of a list of ~four~ three items though and the terminology is ill-defined. For instance, software development increasingly includes the automation of what used to be software operations. That's always been the case, but increasingly so since the coining of "devops". Aug 4, 2021 at 9:51
  • Another item from the list is "software tools commonly used by programmers". This tends to include language-specific package managers like npm and maven. Nix is the closest thing I know of for a bash-specific package manager. It allows the language to be used like a properly managed and packaged scripting language, like python. Would the question "how can I find the correct python package for a given class" be an off-topic question? Aug 4, 2021 at 9:58

2 Answers 2

7

You can install the nix-index package, build the index and then use nix-locate command:

[nix-shell:~]$ nix-locate '/bin/grep'
perl532Packages.grepmail.out                     75,569 x /nix/store/i4krsr02b3yymqhzz9kbz066rkjkn5zl-perl5.32.1-grepmail-5.3111/bin/grepmail
perl530Packages.grepmail.out                     75,569 x /nix/store/vc2iv0zi7kb0fr04gahyx142i30xi0g6-perl5.30.3-grepmail-5.3111/bin/grepmail
patchutils_0_3_3.out                                  0 s /nix/store/yfl83agm8396xw9hir1rwvdanz13h9w5-patchutils-0.3.3/bin/grepdiff
patchutils.out                                        0 s /nix/store/wk1yk22f0f6ai478axaqr0yvwy6q7xl5-patchutils-0.3.4/bin/grepdiff
(patchutils.out)                                248,584 x /nix/store/6jysbyhc43sjvfiyh1bpvi1n3zbz212r-bootstrap-tools/bin/grep
ipinfo.out                                    4,293,096 x /nix/store/7p4g03bi15705ipbkrc7vhb42cvgc54f-ipinfo-2.0.1/bin/grepip
grepm.out                                         1,540 x /nix/store/mfhzjhz2f3mwbg1pq1diblqfdcmcffhs-grepm-0.6/bin/grepm
grepcidr.out                                     19,576 x /nix/store/7x10lzg5389flnjhfwh4xycqi835knfy-grepcidr-2.0/bin/grepcidr
gnugrep.out                                     271,716 x /nix/store/ba3bf20z5rmd9vgyzsgamvwvb3i1idfn-gnugrep-3.6/bin/grep
(unixtools.col.out)                              27,660 x /nix/store/0h4ih2jvl9gv3dnmld2vq5iyyv41cy7v-text_cmds-99/bin/grep

The Nix Cheatsheet provides a helpful list of corresponding commands in Nix and Ubuntu.


Indexing takes some time (depends on network speed and also the size). It can be reduced by using --filter-prefix '/bin/' when you're looking for utilities (8:10 -> 2:50 minutes in my case). Also interaction can be reduced by indexing right after invoking the shell:

$ nix-shell -p nix-index --command 'nix-index --version; time nix-index --show-trace --filter-prefix '/bin/'; return'
Nixpkgs Files Indexer 0.1.3
+ querying available packages
+ generating index: 55661 paths found :: 23483 paths not in binary cache :: 08533 paths in queue
Error: fetching the file listing for store path '/nix/store/siv7varixjdfjs17i3qfrvyc072rx55j-ia-writer-duospace-20180721' failed
Caused by: response to GET 'http://cache.nixos.org/siv7varixjdfjs17i3qfrvyc072rx55j.ls' failed to parse (response saved to /run/user/1000/file_listing.json.2)
Caused by: expected value at line 1 column 1
+ generating index: 66306 paths found :: 23630 paths not in binary cache :: 00000 paths in queue
+ wrote index of 2,742,453 bytes

real    2m50,553s
user    2m39,151s
sys 0m26,571s

[nix-shell:~]$ nix-locate /bin/grep
...
(irccloud.out)                                        0 s /nix/store/dv7klxqz8pmyml05nrs5f5ddd3hb9nsw-irccloud-0.13.0-usr-target/bin/grep
fpc.out                                             732 r /nix/store/4p5nx2csq7xmag9cbkmg54qzj6kxr71j-fpc-3.2.0/bin/grep.tdf
gnugrep.out                                     257,000 x /nix/store/z3q9q9549ci7kbdgyq99r6crnvrky6v3-gnugrep-3.7/bin/grep
grepm.out                                         1,596 x /nix/store/746bg318dq0wm1z23lllbg74ymdyac3r-grepm-0.6/bin/grepm
grepcidr.out                                     22,088 x /nix/store/sja30zvm5nw7ic7gwddc3h89rdgiyza4-grepcidr-2.0/bin/grepcidr
...
2
  • 3
    nix-index took hours to build the index, but then it worked fine. Thanks for this! Aug 4, 2021 at 19:24
  • I tried running nix-index as above on a VM with 2G ram, and it soon started swapping. Nov 17 at 19:35
2

Unlike other Linux package managers that allow a package to install its files all over your system, Nix keeps all the files for a package together inside a single directory, which is named after the package. That directory lives inside /nix/store, and the name of that directory usually gives you a big clue about where the package was defined.

For example, if you have a utility on your PATH named nix-build and you are wondering where it came from, you could try this:

$ realpath $(which nix-build)
/nix/store/5hdmx9yk7gr71b98j4vh9271k0zg5jis-nix-2.2.1/bin/nix

Then we see that it comes from a package named nix. Roughly speaking, that is the name field from code that defined the derivation. The derivation name is not exactly the same as the attribute path that you use to refer to the derivation in the nixpkgs code, but it is still a good clue.

3
  • This only applies to packages in your environment and, as you mentioned, it doesn't give you the attribute, but it's uniquely useful when you're working with custom packages that aren't in Nixpkgs. Aug 4, 2021 at 10:15
  • Yeah, I should add that if the file isn't on your PATH, you wouldn't run which but you can still use realpath to resolve symbolic links and find its real location in the file system. Aug 4, 2021 at 13:11
  • In my case, the command was not installed on the system via nix, so the above trick did not work. I think this answer is nevertheless very helpful for some people finding this. I re-worded the question to make sure that both cases are covered. Aug 4, 2021 at 19:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .