How to invoke `nix-shell` with the contents of an URL (e.g., a raw GitHub link)?

Cross-posting from Unix & Linux Stack Exchange.

Saving it to file, and using that temporary file works fine,

$ url="https://raw.githubusercontent.com/toraritte/shell.nixes/main/deno-latest-shell.nix"

$ curl $url > default.nix

$ nix-shell
# or
$ nix-shell default.nix

but how can one do this without using a temporary file? Here’s what I tried so far:

Pipe

$ curl $url | nix-shell -

This downloads the file and the … just nothing happens.

$ curl $url | nix-shell

This will throw an error that there is no default.nix (of course).

Process substitution

Using the <() operator (archive):

$ nix-shell <(curl $url)

# ... output...
error: getting status of '/dev/fd/pipe:[11284302]': No such file or directory

But when I change nix-shell to cat, it works, just as if I had saved the curl output into a regular file, and printed its contents.

(Maybe hitting the same issue with this approach that is explained in Why doesn’t the process substitution <() work with ssh -F?)


(I know there is nix-shell -E, but it would probably be problematic even if my specific example Nix expression didn’t contain comments…)

1 Like

Maybe not the nicest way to do this, but behind an alias/function it’s probably okay-ish.

This works for me:

f=$(mktemp); cp shell.nix "$f"; nix-shell "$f"; rm "$f"

Obviously replace the cp-invocation with your curl command.

Maybe also worth filing an issue over, as cat ... | nix-shell - seems like it should work, but maybe it’s some subshell-stuff that makes it fail…

I.e., this also fails (given shell.nix exists):

true | nix-shell shell.nix
1 Like

Thanks, I thought about taking the alias route, but notion is that this should work out of the box when I’m switching computers. (Interestingly, the solution in the the linked Stackexchange thread is using zsh’s special process substitution operator =(...) which is the same as your suggestion, but built into the shell itself.)

This problem seems to be the same as the one in the linked Stackexchange thread regarding ssh -F, but I don’t know enough about the topic if that this is by design or by accident, and this is not that crucial anyway. Although, it is indeed baffling that true | nix-shell shell.nix fails, thanks for finding this!

1 Like

@jtojnar provided the answer on Stackexchange:

nix-shell -E "import (builtins.fetchurl $url)"

Also drew my attention to the NixOS/nix issue of Feature request: Use nix eval with process substitution or with pipes · Issue #2734 · NixOS/nix · GitHub which describes the same problems I ran into when trying to use pipes or <(...) so I updated it as well.

2 Likes