Table of Contents
Introduction
This is a fish shell script to source environment variables from an ‘.env’ file, to hide sensitive information from your shell history or publicly accessible config. Information in ‘.env’ files can vary from API keys, to database passwords, to local development settings, plus a plethora of other possibilities. As a result of the sensitive nature of the information in these files, it is important to keep in mind how they are accessed and used while developing. A common practice to access these variables (especially when their needed across multiple tools), is to read them into the shell environment, and then access them from there. Storing these variables in the shell environment is not always the best option to keep ‘.env’ secrets secure, so be mindful of the shell history if you are storing sensitive information in the shell environment.
Usage
In my case, most of the time I read ‘.env’ files into the shell environment is for my editor, neovim. Neovim offers a feature rich plugin ecosystem, similar to VSCode. Neovim plugins usually need to be configured when they are installed. It might be jarring at first, for new users, to install something and not have it work out of the box. Especially as newer AI tools are becoming more common, having a method of sourcing your editor with API KEYS makes getting ‘shiny’ feautre’s working more secure, faster and easier. can be a daunting task. The method I’ve found most success to provide things of this nature across my entire development environment is by reading them, upon initialization of my fish config. Then all my editor or other tools need to do to access the API KEY is read the value from the shell environment variable. Not only does this help keep my entire system consistent, but it also allows me to keep my editor configuration public, without exposing my API KEYS.
Walkthrough/Setup
Here is how my chapgpt API key is setup to be used across my entire system’s tooling:
- Create an API key in chatgpt, (you might have to make a new, if you don’t have access to it).
- Store the API key where ever you want. For this walkthrough we’ll be putting it in the
file
~/.config/chatgpt/.openai_key
.This is our ‘.env’ file that will be read when we start our shell. Feel free to use the .env file extension when setting this up on your own machine, but it is not required. For this walkthrough to work properly, you’ll want your ‘.env’ files to be formatted with syntax of the form “KEY=VALUE”, where the key is the name of the variable to source.
# NAME_OF_VARIABLE=VALUE_OF_VARIABLE
OPENAI_API_KEY=xx-XXXXXXXXXXXXXXXXXX
- Create a fish function to read the ‘.env’ file into the shell environment.
You will want to call this function when the shell is initialized in the
~/.config/fish/config.fish
. We will refer to this function asload_env_vars
in this walkthrough. Here is how I setup myload_env_vars
function:
function load_env_vars -d "Load variables in a .env file"
set lines (cat $argv | string split -n '\n' | string match -vre '^#')
for line in $lines
set arr (string split -n -m 1 = $line)
if test (count $arr) -ne 2
continue
end
set -gx $arr[1] $arr[2]
end
end
This function is modified to skip lines that start with a
#
character. It essentially reads each line of a file into an array, and uses theset -gx
command to expose the variable to the shell environment.
- Call the
load_env_vars
function in your~/.config/fish/config.fish
file. Here is how I setup my~/.config/fish/config.fish
file:
# ..................
# other config stuff
# ..................
# Load environment variables from .env file
load_env_vars ~/.config/chatgpt/.openai_key
- Restart your shell.
- Test that the environment variable is now available in your shell
environment. A simple
echo $OPENAI_API_KEY
should print out your API key. - Use the environment variable in your editor or other tools. In my case, I use the neovim plugin ChatGpt.nvim.
Conclusion
The concept of env
variables, is to allow for subprocesses to inherit values their
parent process (i.e., the shell) has access too. This makes storing the private
environment variables accessible to other tools by only being defined once.
Keeping the values in a singular location, makes it harder to accidentally
expose the values in a publicly accessible space.
However, as I mentioned in the introduction, env
variables
can come in a variety of forms. Most programming languages have a way to access
these values, and locally scoped project env
variables should probably not
be exposed to the shell environment. Learning the pattern recognition for
what the best approach to handling env
variables is something that should feel
natural, and not forced.