Getting the current system from the command line

Hello all

I feel like this is probably simple but I haven’t yet found the answer. How do I get the current system, from the command line? For example, if I’m on x86_64-linux, is there a way to run a nix command which returns that value?

Thanks!

Why do you need this information from Nix? (Is there some specific reason that echo "$(uname -m)-$(uname -s)" or even just uname -ms won’t suffice?)

Thanks, yes, it looks like "$(uname -m)-$(uname -s)" gets me close. To ask the obvious question, though, does this work on all systems on which nix can run, and does nix’s system variable always correspond to this output?

Nix supports so few systems that at this point in time it is not really an issue to find out which exact string is needed. See the ‘Output schema’ page on wiki: Flakes - NixOS Wiki

<system> is something like “x86_64-linux”, “aarch64-linux”, “i686-linux”, “x86_64-darwin”

Considering anyone approaching Nix knows at least enough about computers to find out the combination of architecture and OS on their machine, I think this is sufficient.

Nixpkgs supports quite a few systems actually:

nix-repl> pkgs.lib.systems.doubles.all
[ "i686-cygwin" "x86_64-cygwin" "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin" "i686-freebsd" "x86_64-freebsd" "aarch64-genode" "i686-genode" "x86_64-genode" "x86_64-solaris" "js-ghcjs" "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux" "mips64el-linux" "powerpc64-linux" "powerpc64le-linux" "riscv32-linux" "riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux" "mmix-mmixware" "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" "aarch64_be-none" "aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none" "msp430-none" "or1k-none" "m68k-none" "powerpc-none" "powerpcle-none" "riscv32-none" "riscv64-none" "rx-none" "s390-none" "s390x-none" "vc4-none" "x86_64-none" "i686-openbsd" "x86_64-openbsd" "x86_64-redox" "wasm64-wasi" "wasm32-wasi" "x86_64-windows" "i686-windows" ]

Blown up quite a bit by the many different OSes on those platforms of course, but it’s not necessarily trivial to just pick one. nix itself can support far more, it’s written in C specifically so that bootstrapping is easily feasible.

@harris-chris if you want the double to use for any nix variables on your computer, use in nix repl:

nix-repl> builtins.currentSystem
"x86_64-linux"

builtins.currentSystem is also available in a lot of nix contexts (though specifically not flakes).

3 Likes

Wow, that is a lot. Shouldn’t some of these be dropped at this point? e.g. ARMv7 and x86 darwin haven’t been available and supported for a while now.

Thank you. Is there any way to capture this output programmatically from the cli? nix repl 'builtins.currentSystem' doesn’t seem to work here. nix repl and then nix-repl> builtins.currentSystem does but can’t be easily called and have its output captured by other processes.

If you’re using a flakes-enabled Nix:

nix eval --impure --raw --expr 'builtins.currentSystem'

Otherwise:

nix-instantiate --eval --expr 'builtins.currentSystem'

The latter outputs a quoted string, you may want to use the --json flag and pass the result to jq -r '.'

2 Likes

Yes - thank you - that works great.

In fairness, I use “supports” pretty lightly there :slight_smile: The binaries aren’t pre-built by hydra for most of those platforms, and I imagine most of them see hardly any testing by anyone. But the various system variables can take any of those values and produce something meaningful (even if it’s just an error you could take and start debugging from), which is my main point.

Fully “supported” is mostly x86_64, aarch64 and i686, combined with linux and darwin, if you go by what hydra builds continuously: Hydra - Machine status. But even there the definition of “support” is unclear, there are many packages that don’t build on all those platforms and a lot of them never will. Breakage is significantly more common on non-x86_64, too.

i686 has especially much breakage IME (since my flakes tend to build their devShells for all architectures because I convince myself I might one day try to use my dev shell on an old 32 bit system every time I wonder if it’s worth the effort). Hard to call it unsupported when there is a set of hydra jobs for it, though.

Another definition of “supported” may be what is listed as exposed for flakes (previously the attribute for that was in fact called “supported”):

nix-repl> pkgs.lib.systems.flakeExposed
[ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "armv6l-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "aarch64-darwin" "armv5tel-linux" "powerpc64le-linux" "riscv64-linux" ]

But this again includes a bunch of architectures that aren’t actively “supported” by anyone to my knowledge.

It becomes even more wonky when you think about how many abandoned or otherwise unmaintained packages are just lying around. Hard to call any of them “supported”, so really, I think the distinction is purely a definition one.

Either way, if you ask me “what value should I put in the system variable”, I don’t think “pick which ever one sounds right between x86_64-linux and aarch64-linux” is the right answer, given how many things have references in the nixpkgs source.

IIUC builtins.currentSystem doesn’t always return the native processor architecture. For example, if you installed Nix through rosetta, does not builtins.currentSystem evaluate to x86_64-darwin even on an ARM mac?

The one I am relying on instead is:

$ nix run github:nix-systems/current-system
aarch64-darwin