let _=''1
# shell script starts here
echo "I am a shell script"
echo "followed by a Nix expression."
exit
''; in
# nix expression starts here
{
This = "is a Nix expression";
after = "a shell script.";
}
$ nix eval --file default.nix
{ This = "is a Nix expression"; after = "a shell script."; }
$ bash default.nix
I am a shell script
followed by a Nix expression.
One caveat is that it would be painful if you want to use ${...}
in the script though. If the string interpolation ${...}
in bash does not have special characters, you can use unquoted ''${...}
.
Update: With this version, you can have variables that are both accessible from Bash and from Nix, and there is a variable that you can refer to in Bash to get the contents of the Nix expression, and also a variable that you can refer to in Nix to get the contents of the Bash script.
#!/usr/bin/env bash
let _=0;
commonVariable="I can be accessed in both the shell script and the Nix expression";
__='';nixExpression="$(cat <<'NIX_EXPRESSION' | sed '1d;$d'
'';finalAttrs=
{
This = "is a Nix expression";
inherit commonVariable bashScript;
}
;___=''
NIX_EXPRESSION
)";_='';bashScript=''
echo "I am a shell script followed by a Nix expression."
echo "The common variable is: $commonVariable"
echo "The Nix expression is: $nixExpression"
exit
'';in finalAttrs
$ ./default.nix
I am a shell script followed by a Nix expression.
The common variable is: I can be accessed in both the shell script and the Nix expression
The Nix expression is:
{
This = "is a Nix expression";
inherit commonVariable bashScript;
}
$ nix eval --file default.nix --json | jq
{
"This": "is a Nix expression",
"bashScript": "\necho \"I am a shell script followed by a Nix expression.\"\necho \"The common variable is: $commonVariable\"\necho \"The Nix expression is: $nixExpression\"\n\nexit\n",
"commonVariable": "I can be accessed in both the shell script and the Nix expression"
}