Skip to content

Apologies for the appearance of the site. I'm designing in public!

Command line terminal

Dotenv for bash

Published on Thursday, 7 October 2021.
At 344 words, this article should take about 2 minutes to read.

I have, on occasion, had to use the same secret variables in my codebase (JavaScript) and my build scripts (Bash).

Shut up and show me the code!

export $(egrep -v '^#' .env | xargs)

Back to the beginning

A common pattern to keep some variables hidden from prying eyes involves storing them in an .env file in the root of your project and not committing it to your repository.

# .env


Using the extremely popular dotenv npm package allows us to reference the variables in our codebase.

const { SUPER_SECRET_API_KEY } = process.env;
// or
const key = process.env.SUPER_SECRET_API_KEY;

This is great! And it works really well!

One of the things I use .env for is defining my environment locally. When I deploy my code through the CI Pipeline, this environment variable is available without me defining it: ENV=production or ENV=development. Exposing this to my codebase using dotenv allows me to do stuff like;

  const { ENV } = process.env;

if (ENV === 'production') {
// Do production version
} else {
// Do non-prod version

As it happens, I also use my ENV variable in bash scripts, for example;


if [ $(ENV) = 'production' ]; then
# Run the build-production script
# This will strip logs, minify, uglify, and all that good stuff
# Run the watch script
  ENV=production bash

Notice how I have to define ENV inline here. That's because bash can't read the .env file.

If you wanted to permanently expose that variable to bash (so you don't have to type it out every single time), you would export it;

  export ENV = production

echo $ENV # production
echo $(ENV) # production

This is all well and good… until you have 5, 10, 100 variables to export! 🙄

Enter the handy snippet! 🎉

  export $(egrep -v '^#' .env | xargs)

By looping through every line in the .env file and exporting it as a bash variable (unless, of course, it begins with a # - that's a comment 😁), we can save ourselves, potentially hours of typing!


Cover image courtesy of Gabriel Heinzer.


In almost all cases, the comments section is a vile cesspool of Reply Guys, racists, and bots.

I don't want to have to deal with that kind of hell so I don't have a comments section.

If you want to continue the conversation, you can always hit me up on Mastodon (which is not a vile cesspool of Reply Guys, racists, and bots).

onward-journeys module