Use nix values in a shell?

Hi,

I’d like to extract some values from a nix file to be used in a shell script. I wonder if there is an easy to do that?

For example, if the nix file evaluates to { a = 1; b= "c"; }, is there an easy way to generate the text:

a=1
b="c"

So it can be easily sourced into a script?

I guess you’re looking for something like:

let
  inherit (lib.strings) concatStringsSep;
  inherit (lib.attrsets) mapAttrsToList;
in
  concatStringsSep "\n" (mapAttrsToList (k: v: "${k}=${builtins.toString v}") attrs);

There are probably lots of implementations of this in nixpkgs. Maybe there is an undocumented library function already.

Watch out for any escaping you may need to do, you might find the lib.strings helpers handy: Nixpkgs 22.05 manual

Alternatively, if this is literally for a shell script, use lib.strings.toShellVars.

What are you trying to achieve?

Could it be something like this:

pkgs.runCommand "example" {
  a = 1;
  b = "c";
  foo = "bar";
} ''
  echo $a $b $foo > $out
'';

@TLATER toShellVars helps a lot, thanks.

@Atemu, I need to use the value in my custom shell script. This seems to mean I need to ask nix to generate my shell script. Thanks for the tip though, I didn’t know runCommand accepts env vars.

Not per-se, it depends on how you use the shell script. You have the option of creating an environment file for something launched with systemd, or using a wrapper to set up the environment before the script runs.

So if you’d rather avoid hard-coding things with nix, it would be helpful if you could elaborate at least on how you will be using the script.

it would be helpful if you could elaborate at least on how you will be using the script.

I’m writing a script to help me install nixos. I need to extract the path value (relative to user’s home folder) of my nixos-config folder, to determine where to copy nixos-config to my new machine. Since nixos won’t exist yet in this use case, using lib.strings.toShellVars should be the correct solution?

Thanks for the suggestion. I should’ve made my use case clear in my OP.

1 Like