How to set environment variables in bash and zsh
By Flavio
Published · Updated
Tagged: CLI
Learn how to set environment variables in Bash and zsh, persist them in .bashrc or .zshrc, and avoid the common $VAR command-not-found mistake.
An environment variable is a name and a value that a process passes to the programs it starts. Your shell has a set of them. Every command you run inherits a copy.
Setting one works the same way in Bash and zsh. Assign the value and export it in one line:
export APP_ENV=development
export is what makes the difference. A plain APP_ENV=development is only a shell variable. Child processes do not see it. After export, node, git, and anything else you launch can read process.env.APP_ENV or $APP_ENV.
How to read a variable
Do not type $APP_ENV on its own. The shell replaces it with the value, then tries to run that value as a command:
$APP_ENV
bash: development: command not found
Print it instead:
echo "$APP_ENV"
Or look for it in the exported environment:
env | grep '^APP_ENV='
The first prints development. The second prints APP_ENV=development. Quote the expansion. A value with spaces splits into several words if you leave the quotes off.
One value for one command
Often you do not want to change the current shell. Put the assignment in front of the command:
APP_ENV=test node test.js
node sees APP_ENV=test. When it exits, your shell is unchanged.
Fish 3.1 and later accepts that same prefix. On older Fish, prepend env:
env APP_ENV=test node test.js
env works in Bash and zsh too, if you want one syntax everywhere.
To export a variable for the whole Fish session, use set -gx APP_ENV development. Put that line in ~/.config/fish/config.fish if you want it to persist, or use set -Ux for a universal variable.
Make it stick
An exported variable lives only in the current shell. Close the window and it is gone.
Add the export line to the startup file your shell reads. That is ~/.zshrc for zsh and ~/.bashrc for interactive Bash. Then reload it, or open a new terminal:
source ~/.zshrc
If the variable does not show up, check which shell you are in with echo "$SHELL". Editing .bashrc while the terminal runs zsh is a classic miss.
A variable you’ll set this way often is NODE_ENV. See Node, the difference between development and production for what it changes and where to set it on a server.
Values with spaces
Quote the value when it has spaces or special characters:
export GREETING='hello there'
Without quotes the shell treats there as a separate word, and the assignment fails.
Remove a variable
unset drops it from the current shell:
unset APP_ENV
It does not edit your startup file. If you added export APP_ENV=... to .zshrc, remove that line too, or the next shell puts it back.
Secrets
Environment variables are visible to the process, to its children, and to anyone who can run ps on that machine. They are convenient, not encrypted storage. Do not commit API keys to a startup file you share, and do not print them in logs.
Want me to talk about your product? You can sponsor this site.
Related posts about cli: