Why does `nix nar cat` produce no output?

I’m tempted to just write an issue in GitHub - NixOS/nix: Nix, the purely functional package manager, because I think this is a bug, but I’ve not used with nix nar before so I was hoping to get a sanity check before I did.

Here’s a session:

❯ mkdir a
❯ echo 'c' | save a/b
❯ cat a/b
	c

❯ nix nar dump-path ./a | save a.nar

❯ nix nar ls --recursive a.nar /
	./b

❯ nix nar cat a.nar /b  # no output, why?

❯ ls -l a
	╭───┬──────┬──────┬────────┬──────────┬───────────┬───────────┬───────────┬──────┬───────┬──────┬───────────────┬───────────────┬───────────────╮
	│ # │ name │ type │ target │ readonly │   mode    │ num_links │   inode   │ user │ group │ size │    created    │   accessed    │   modified    │
	├───┼──────┼──────┼────────┼──────────┼───────────┼───────────┼───────────┼──────┼───────┼──────┼───────────────┼───────────────┼───────────────┤
	│ 0 │ a/b  │ file │        │ false    │ rw-r--r-- │         1 │ 106006727 │ matt │ staff │  1 B │ 2 minutes ago │ 2 minutes ago │ 2 minutes ago │
	╰───┴──────┴──────┴────────┴──────────┴───────────┴───────────┴───────────┴──────┴───────┴──────┴───────────────┴───────────────┴───────────────╯

❯ nix nar ls --long a.nar /b
	-r--r--r--                    1 b

I think that what I’m doing here is creating a single file nar archive whose file contains a single byte. I think that the various ls commands confirm that there is data in there. But cat prints c, as expected, while nix nar cat prints nothing, which is unexpected.

Am I misunderstanding something? Why can’t I see the data in there?

I can’t reproduce this, so it’s time to look into system, environment, version etc differences. Can you give some more relevant details?

PS: +1 for nu, but that’s not the difference, it works for me with nu or bash

That’s exactly the kind of sanity check I needed, thank you. I originally found this on my work laptop (macOS). While trying to recreate it on my personal desktop (NixOS), I noticed this:

❯ nix --version
    nix (Nix) 2.18.1

❯ nix nar cat a.nar /b

❯ nix nar cat a.nar /b | save output

❯ cat output
    c

It would seem that, at least with this version on nix on my machine with my config (be it in MacOS or in NixOS), the command won’t provide output if stdout is a tty.

The weird thing is, when I try it in docker, it works regardless of version, regardless of whether stdout is a tty.

❯ [2.17.1, 2.18.1, 2.19.3, latest ] | each { |it|
∙ let image = ("nixos/nix" | append $it | str join ':')
∙ let script = $"
∙ echo 'experimental-features = nix-command' > /etc/nix/nix.conf
∙ mkdir a
∙ echo c > a/b
∙ nix nar dump-path ./a > a.nar
∙ nix nar cat a.nar /b
∙ echo ---
∙ "
∙ echo $image
∙ $script | docker run -i $image sh
∙ }

	nixos/nix:2.17.1
	c
	---
	nixos/nix:2.18.1
	c
	---
	nixos/nix:2.19.3
	warning: 'nix nar dump-path' is a deprecated alias for 'nix nar pack'
	c
	---
	nixos/nix:latest
	warning: 'nix nar dump-path' is a deprecated alias for 'nix nar pack'
	c
	---

❯ docker run -it nixos/nix:2.18.1
	bash-5.2# echo 'experimental-features = nix-command' > /etc/nix/nix.conf
	bash-5.2# mkdir a
	bash-5.2# echo c > a/b
	bash-5.2# nix nar dump-path ./a > a.nar
	bash-5.2# nix nar cat a.nar /b
	c
	bash-5.2# exit

❯ docker run -it nixos/nix:latest
	bash-5.2# echo 'experimental-features = nix-command' > /etc/nix/nix.conf
	bash-5.2# mkdir a
	bash-5.2# echo c > a/b
	bash-5.2# nix nar dump-path ./a > a.nar
	warning: 'nix nar dump-path' is a deprecated alias for 'nix nar pack'
	bash-5.2# nix nar cat a.nar /b
	c
	bash-5.2# exit

I get the same behavior in both wezterm and console and when I ctrl+alt+f1 out of my graphical environment. Same with sh, zsh, bash, and nushell

Maybe there’s something weird going on in the repo where my flake lives (used to configure both machines).

Anyhow, I have a workaround (pipe it somewhere), so I’m not sure how deeply I’ll dig on this. It sure is strange though. If the curiosity gets me, I’ll recreate my config step at a time and see if I can find the cause.

1 Like