As in this question for Bash, I'd like to have a simple .env
file or similar that I can read into the Nushell environment. While I'll typically use this for API keys, to simply re-use the same example from that question:
MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"
Of course, Nushell is not POSIX, so none of those answers will work.
The Nushell syntax for setting an environment variable is:
$env.foo = "value"
And while it's possible to source-env
a file that modifies the environment, that file needs to be a valid Nu script, which the .env
is not.
I'd like to keep the structure of the file "standard" so that it can be used with other shells and tools, but how can I use it to set environment variables in Nushell?
Took me a few tries to get right, so throwing this out in case it helps others (and so I can find it easily in the future). I found two (now three) ways to do this in Nushell.
Disclosure: Both @CptPiepmatz who answered and I are now maintainers of Nushell at the time of the most recent edit, but neither of us were at the time we original asked/answered.
parse
itSee @CptPiepmatz's answer, which I've accepted as it is more robust and efficient than either of my original two solutions below. I'm leaving them as alternatives in case they are useful to anyone else.
The file format as it stands is a valid TOML file, and Nushell has built in support for TOML as structured data. As a result, we can easily read it with:
> open .env | from toml
╭─────────────────────────┬─────────────────────────╮
│ MINIENTREGA_DESTINO │ ./destino/entrega-prac1 │
│ MINIENTREGA_FECHALIMITE │ 2011-03-31 │
│ MINIENTREGA_FICHEROS │ informe.txt programa.c │
╰─────────────────────────┴─────────────────────────╯
And from there, since the result is a Nushell record, load-env
can be used to load it into the environment:
> open .eenv | from toml | load-env
> echo $env.MINIENTREGA_FECHALIMITE
2011-03-31
TOML also supports comments, so you can have a valid (Bash) commented file as well and from toml
will ignore them.
The caveats are that the file must be valid TOML, including quotes.
Fair warning: I know this seems really hacky, but I've been using this method successfully for a few years now on the Fish shell (also not POSIX) to process Bash scripts, and it also works for this modified use-case on Nushell.
With credit to this great answer on the Bash version of this question:
exec bash -lic "set -o allexport && source ~.env && set +o allexport; exec nu"
This:
exec
s Bash (replacing the current Nushell)source
s the .envexec
s Nushell, replacing the previous BashSince the variables were exported from Bash, they'll now be available in Nu.
Using parse
you can achieve very nice results with only nushell commands.
This function allows opening a .env
file with quotes and without. It also handles comments.
def "from env" []: string -> record {
lines
| split column '#'
| get column1
| filter {($in | str length) > 0}
| parse "{key}={value}"
| update value {str trim -c '"'}
| transpose -r -d
}
Comment handling is done by splitting on #
and getting the first element, then it remove any empty lines. After that it uses the parse
mentioned earlier to parse the lines. Then it trims quotes if any exists. Finally using tranpose -r -d
will transpoe the table into an object.
Then you can do something like open .env | load-env
.
Edit: This is now also part of the nu_scripts repo, you can find it here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With