TL;DR
You can use
env $(cat .env | grep -v "#" | xargs) your_command_expecting_env_vars
to run your_command_expecting_env_vars
providing it the content of .env
like you would do when running FOO=1 BAR=2 your_command_expecting_env_vars
.
TS;WR
Many command lines tool can read, or even expect, values set in environment variables.
It is a common practice to place environment variables contextual to a project in a .env
file in the project root, and there are tools like dotenv
that allow you to load those variables into your application.
Sometimes thought you just need to set a handful of values and cannot be bothered typing FOO=1 BAR=2 BAZ=3 bundle exec foobarbaz
. Or maybe your cli tool expects a token that you don't want to store in the repo, but at the same time cannot type every time.
In such cases it might be useful to place those environment variables in a .env
file, but how to load them?
This is one possible way:
env $(cat .env | grep -v "#" | xargs) your_command_expecting_env_var
Let's disassemble this long command, shall we?
$(...)
will be evaluate it's content before the command is interpreted and run, and replaced with the result, so that what actually is run will be env result your_command_expecting_env_var
.
cat .env
will put the content of the .env
file into the standard output. This would normally be the screen, but in this case there is a pipe operator.
grep -v "#"
is an inverted match grep. By default grep
selects lines containing the given pattern, the string #
in our case, from its standard input. With the -v
, or --invert-match
it will select the lines not matching the given string.
So cat .env | grep -v "#"
results in the content of .env
apart from comment lines sent to the standard output, where xargs
is there to wait for it. xargs
builds an argument list out of its standard input.
This argument list is fed to env
. The synopsis of this command is:
env [-i] [name=value ...] [utility [argument ...]]
What env
does is executing utility
after modifying the environment as specified by the name=value ...
list. And that is exactly the end result that we are looking for 😎
A nice thing to notice is that env
doesn't export the name=value
inputs, so that the environment is not polluted.
Hope you found this article useful, this is the SO answer that inspired and helped me with this approach.
If you need help get in touch with me on Twitter @mokagio, or leave a comment below. And don't forget to hit the share button 😉.
Happy coding, and leave the codebase better than you found it.