Run shell commands in nix expressions

Does nix have a function that can be used to run shell commands during evaluation phase? (or a general purpose exec function)

What environment does nix use when evaluating a derivation? (chroot/normal shell)

If a local file/directory is specified as the build input of a derivation, that file/directory is copied over to nix store and that copy is provided to the builder. Instead I want to use the output of a shell script i’ve written(which uses some local files as input) to be used as the build input of my derivation.

1 Like

I can’t see a use case for this.

evaluation all occurs within nix code

Just have that be in another derivation, write it $out, then read it from the consuming derivation. You can also write arbitrary bash as part of the phases.

2 Likes

Does nix have a function that can be used to run shell commands during evaluation phase? (or a general purpose exec function)

There is builtins.exec. It is guarded by a scary option etc. and for a good reason (see src/libexpr/eval.hh and primops.cc)

What environment does nix use when evaluating a derivation? (chroot/normal shell)

Not sure. I guess there is some alternative plugin if it is too restrictive…

If a local file/directory is specified as the build input of a derivation, that file/directory is copied over to nix store and that copy is provided to the builder. Instead I want to use the output of a shell script i’ve written(which uses some local files as input) to be used as the build input of my derivation.

Technically, I guess you could run a command using a copy of local files into store via ./. reference.

2 Likes

Just have that be in another derivation, write it $out, then read it from the consuming derivation. You can also write arbitrary bash as part of the phases.

The input directory is huge and the derivation needs to use only some of the files from that directory (file filtering logic is non trivial). Adding the directory as a dependency will be too inefficient.

I enabled the option and tried using builtins.exec but that gave the following error:

nix-repl> builtins.exec ["echo" "hello"]
error: undefined variable 'hello' at (string):1:1

Indeed, the builtin executes the program and parses its output. So it tries to parse «hello» and hits undefined variable. The program should output a ready to use chunk of Nix code.

(It does seem to run without sandboxing)

Try with “\“hello\””, so that nix gets a string instead of an identifier.

One use case would be creating a timestamp for log files, etc. and the builtins.readFile (pkgs.runCommand ... )) pattern in the How to create a timestamp in a Nix expression? thread could be used as a workaround.