Can I inspect the installed versions of system packages?

When I use environment.systemPackages to install packages, they don’t show up in nix-env -q. Is there any way to check what package versions I have installed? In the common case I could spot-check individual packages by looking at what’s in my current channel, but that won’t help if I roll back my environment, or if I update my channel separately from rebuilding my environment.

I’d simply use which <command> for binaries in $PATH and language-specific tricks for libraries. =)

More precisely, I use ls -l $(which command)

1 Like

readlink -f $( which command ) works even better.

2 Likes

What I actually want to do is get the versions of all installed system-level packages, similar to what nix-env -q gives me for user-level packages, so I can then easily figure out what changed after I do a nixos-rebuild switch --upgrade.

1 Like

couldn’t you eval the attributes in the repl or something?

Shouldn’t this still be possible with nix-env either running as root or with the correct -p argument to get to the default/system-level profile? I’m not on a NixOS box moment and can’t easily verify.

nix-instantiate --strict --eval -E 'builtins.map (p: p.name) (import <nixpkgs/nixos> {}).config.environment.systemPackages'

might do the trick.

nix-instantiate --strict --json --eval -E 'builtins.map (p: p.name) (import <nixpkgs/nixos> {}).config.environment.systemPackages' | nix run nixpkgs.jq -c jq -r '.[]' | sort -u

to get a bit nicer output.

7 Likes

Interesting. But if I run nix-channel --update will this give me the currently-installed versions or will it give the versions that would be installed if I then run nixos-rebuild switch? Because I’m assuming it’ll give me the packages from the channel.

From whatever is in <nixpkgs> channel, yes. Unfortunately nix doesn’t really keep the information of “packages” around after evaluating the derivation, since there’s no such thing as a package. Someone please correct me if I’m wrong.

So the closest you can get with this approach is to make sure you check out the corresponding channel of your currently running system and evaluate the config of that.

so is this description accurate?

I believe a slightly more accurate way of stating that option’s description is “The set of packages that will appear in /run/current-system/sw after a nixos-rebuild switch”.

Given that the package name and version end up in the derivation name, all I really need is a way to list the names of all of the explicitly-requested derivations from the system environment (i.e. nothing installed to satisfy a dependency). I don’t know if it’s possible to do that though.

There is a simple for that (assuming you are using a single channel setup).
First get your current nixpkgs rev.

derped@Lilim ~ $  realpath /run/current-system 
/nix/store/a2i28vlvxy8vwgw024gq699nkb1am56r-nixos-system-Lilim-19.09pre175916.1fc591f9a5b

In my case that is 1fc591f9a5b.
Now just run the command @manveru provided with the desired channel.

nix-instantiate -I nixpkgs=https://github.com/nixos/nixpkgs/archive/1fc591f9a5b.tar.gz --strict --json --eval -E 'builtins.map (p: p.name) (import <nixpkgs/nixos> {}).config.environment.systemPackages' | nix run nixpkgs.jq -c jq -r '.[]' | sort -u

There is probably a way to properly parse the systems derivation file but I have no idea how.


EDIT: I should properly read through previous posts before I post something… he already mentioned checking out the desired channel.

How about something like this in your configuration.nix to save a file in /etc/current-system-packages:

environment.etc."current-system-packages".text = 
let
  packages = builtins.map (p: "${p.name}") config.environment.systemPackages;
  sortedUnique = builtins.sort builtins.lessThan (lib.unique packages);
  formatted = builtins.concatStringsSep "\n" sortedUnique;
in formatted;

(basically what @manveru suggests… but tied to the currently active configuration)

Seems to work on my computer… although I’m still in the ‘beginner phase’, so I’d expect there is a much better way of expressing the above.

Even better would be to store some extra metadata and not just the package name (e.g. the derivation) in a structured format. I expect there is a way to then use that information to compare the potential changes after a nix-channels --update then…

5 Likes

I know this is thread is very old, but I liked this article:

In particular,

nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq

which I shortened slightly to:

nix-store --query --requisites /run/current-system | cut -d- -f2- | sort -u

and captured in a one-liner.

7 Likes

That’s useful, but it gives me a lot more than just what’s in environment.systemPackages, or what I get from modules (more generally, than what’s in my profile). For example, I don’t think libtiff-4.0.10 is part of my profile, I expect that’s just a dependency. Is there any way to filter this down to just stuff in my profile?

1 Like

List binaries in profile:

find /run/current-system/sw/bin/ -type l -exec readlink {} \; | sed -E 's|[^-]+-([^/]+)/.*|\1|g' | sort -u

Output format:

gnugrep-3.3
gnumake-4.2.1
gnupg-2.2.17
…

Remove the bin/ suffix in the above command to list all drv outputs used in the profile.

2 Likes

Right. That’s a little different that what you want. I do like seeing the transitives though.