Nix-shell shebang: default.nix: No such file or directory

As I’ve only started using nix / nixos relatively recently, I usually use flakes and new-style nix commands. I swear I’ve used the nix-shell shebang trick before, but for some reason can’t get it to work today – keep getting an error about it expecting default.nix and not finding it.

After reading https://nixos.wiki/wiki/Nix-shell_shebang

$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 5.15.85, NixOS, 22.11 (Raccoon), 22.11.20221224.dac57a4`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.11.1`
 - channels(root): `"nixos-22.11"`
 - channels(n8henrie): `"nixpkgs-22.11"`
 - nixpkgs: `/home/n8henrie/.nix-defexpr/channels/nixpkgs`
$ cat <<'EOF' > foo.sh
#! /usr/bin/env nix-shell
#! nix-shell -i bash

printf "hello world\n"
EOF
$ chmod +x ./foo.sh
$ ./foo.sh
error: getting status of '/tmp/tmp.bIWspg0FPp/default.nix': No such file or directory
$ $PWD/foo.sh
error: getting status of '/tmp/tmp.bIWspg0FPp/default.nix': No such file or directory
$ bash foo.sh 
hello world

Seeing same behavior on MacOS (aarch64) and NixOS (x86_64).

This thread is a little hard to follow but looks related: . / c u r s e d . n i x - #7 by deliciouslytyped, which is why I tried the absolute path (with $PWD).

Why am I not able to run ./foo.sh here?

2 Likes

You forgot the -p bash part.

Given that bash is part of stdenv, you can probably get away with some other -p argument, but you need at least one, so that you’re invoking the right use mode of nix-shell.

1 Like

tejing is giving you the right advice, but to clarify: without another -p flag, nix-shell is trying to run shell.nix, just like a bare nix-shell invocation.

If it doesn’t find shell.nix, it falls back to default.nix.

When it doesn’t find that, it errors.

Interesting, I thought -p was for dependencies, and -i bash would imply -p bash.

The wiki entry seems to read that way. Should I edit it? (I’d be happy to.)

https://nixos.wiki/wiki/Nix-shell_shebang#Bash

To run bash scripts, set the interpreter with -i bash

#! /usr/bin/env nix-shell
#! nix-shell -i bash

echo hello world

It sure looks like my test script above should work, right?

They’re separate namespaces. Not every package has the same name as its binary, and there’s no dependable database to associate them. For example, how would nix-shell -i awk know it needs -p gawk? (For that matter, sometimes multiple packages provide the same binary name…)

Yeah, that’s wrong, please do fix that.

2 Likes

There is an effort to make a tutorial for nix-shell in the “new” documentation add tutorial for nix-shell in shebang by rapenne-s · Pull Request #325 · NixOS/nix.dev · GitHub

2 Likes