Set Environment Variable Mac: Terminal Commands for PATH Configuration

Published:

Ever typed export MY_VAR = “value” and zsh yelled at you?
That tiny space is a classic gotcha.

This quick guide gets you past it.
You’ll get the exact Terminal commands to set temporary vars, persist them in ~/.zshrc or ~/.bash_profile, and update PATH without breaking core commands.
We cover zsh vs bash vs fish, how to make variables visible to GUI apps with launchctl, and the common pitfalls that waste an hour so you can fix environment issues fast.

Quick Steps to Set an Environment Variable on macOS

VGsIX9S4Q5erKBsK6V5M-g

You type “export variableName = variableValue” in Terminal and zsh throws a syntax error. Try “setenv variableName = variableValue” and you get the same thing. Those spaces around the equals sign are the problem.

The correct syntax drops the spaces: export VAR="value". Run that command and the variable exists in your current shell session. But it only lasts until you close Terminal. To check if it worked, restart your Terminal (Command-Q and reopen), then run echo $VAR. If you see your value, you’re done.

Here’s how to set a temporary environment variable in under 30 seconds:

  1. Open Terminal (Command-Space, type Terminal, Enter).
  2. Type export MY_VAR="test_value" (swap MYVAR and testvalue with your actual variable and data).
  3. Press Enter.
  4. Restart Terminal or open a fresh window (Command-T for a new tab).
  5. Run echo $MY_VAR to verify the value appears.

Copying, editing placeholders, and running these two commands takes about 20 seconds. The restart adds maybe 5 to 10 more. If you’re testing or need a variable for one session, stop here. Want it to survive reboots and new Terminal windows? Keep reading.

Setting Permanent Environment Variables on macOS

5WFdb2cPQSGq344MKbD2jQ

Temporary variables vanish when you close Terminal. To make them stick, you write the export line into a shell startup file that runs every time you open a new shell.

Which file you edit depends on your shell. macOS Catalina (October 2019) and later defaults to zsh. If you’re on zsh, the file is ~/.zshrc. Still using bash (or you switched to bash)? You’ll edit ~/.bash_profile or ~/.bashrc. The tilde (~) is shorthand for your home directory, so ~/.zshrc expands to /Users/yourname/.zshrc.

Once you add an export line to the right file, you need to reload it. Run source ~/.zshrc (or source ~/.bash_profile for bash) in the current Terminal, or close and reopen Terminal. A new session picks up the updated file automatically.

When to use which file:

~/.zshrc is for zsh users. Loaded for every new interactive Terminal window on Catalina and later.

~/.zprofile is for zsh login shells. Less common for local dev work, but some setups prefer it.

~/.bash_profile is for bash login shells. Read once when you log in or open a new Terminal on older macOS or explicit bash sessions.

~/.bashrc is for bash interactive non-login shells. Often sourced from .bash_profile to keep config in one place.

Example commands to persist a JAVA_HOME variable in zsh:

echo 'export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home"' >> ~/.zshrc
source ~/.zshrc

After you source the file, echo $JAVA_HOME should print the path. Every new Terminal session will have JAVA_HOME set without you typing anything.

Updating PATH on Mac to Include New Tools and Binaries

CBiPBZmpRK2PIUKVQooZQQ

The PATH variable tells macOS where to look for executables. When you type javac or brew without a full path, the shell searches each directory in PATH until it finds a match. If the binary isn’t in any of those directories, you get a “command not found” error.

To add a new directory (a custom scripts folder or Homebrew’s install location), you prepend or append it to the existing PATH. The syntax is export PATH="/new/dir:$PATH". Notice the colon separator and the $PATH variable at the end. That preserves all the directories that were already there. If you accidentally write export PATH="/new/dir" without $PATH, you overwrite the whole thing and break system commands like ls and cd.

Common additions and pitfalls:

Prepend when you want your version to override system defaults: export PATH="$HOME/bin:$PATH"

Append when you want system paths searched first: export PATH="$PATH:/usr/local/custom"

Don’t add the same directory twice. It clutters the variable and slows lookups (check with echo $PATH).

Homebrew on Apple Silicon installs to /opt/homebrew/bin. On Intel Macs it’s /usr/local/bin. Add whichever matches your setup.

Use quotes around paths with spaces, though it’s better to avoid spaces in directory names for dev tools.

Verify the change with echo $PATH. You’ll see a colon-separated list. The shell searches left to right, so the first matching executable wins. If /usr/local/bin/python3 appears before /usr/bin/python3, you’ll run the Homebrew version.

Order matters. When you have multiple Python or Node installations, PATH order decides which one runs by default. That’s why most guides tell you to prepend your custom directories. It gives them priority over the OS defaults.

macOS Shell Differences: zsh, bash, and fish Variable Setup

vm2SynNyRQa9YK4VZNeGwA

To find out which shell you’re running, type echo $SHELL. On macOS Catalina and later, you’ll see /bin/zsh. On older systems or if you switched manually, you might see /bin/bash.

Each shell reads different startup files and uses slightly different syntax for environment variables. Zsh and bash both use export VAR="value", but they load from separate config files. Fish uses a completely different command: set -Ux VAR "value", where -Ux makes the variable universal (persistent across sessions and reboots).

Here’s a quick reference:

Shell File to Edit Example Command
zsh ~/.zshrc export MY_VAR=”value”
bash ~/.bash_profile or ~/.bashrc export MY_VAR=”value”
fish ~/.config/fish/config.fish set -Ux MY_VAR “value”

If you’re migrating from bash to zsh (or just switched to a new Mac), you can copy your export lines from ~/.bash_profile into ~/.zshrc. The syntax is identical, so the lines work without modification. Just remember to source the new file or restart Terminal.

System‑Wide Environment Variables and PATH Settings on macOS

jhgj1WczQoW0j_1_3IQiHA

User-level shell files only affect your account. If you need an environment variable or PATH entry for every user on the machine, you edit system files in /etc.

The main system files are /etc/profile (read by all shells on login), /etc/zshrc (zsh-specific), and /etc/bashrc (bash-specific). For PATH-only changes, macOS provides /etc/paths (a plain list of directories, one per line) and /etc/paths.d/ (a folder where each file contributes additional paths).

Because these files affect everyone, you need sudo to edit them. Example:

sudo nano /etc/paths

Add a new line with your directory, save, and exit. The next time any user logs in or opens a new shell, that path is included.

Key points for system-wide config:

Changes apply to all users, so use them sparingly and document what you add.

Restart or log out/log in for changes to take effect across all sessions.

Use /etc/paths.d/ for modular additions. Create a file like /etc/paths.d/mytools and put one directory per line.

If you break /etc/profile or /etc/paths, basic commands might fail. Always keep a backup or second Terminal window open when editing.

Most local dev work doesn’t need system-wide variables. Stick to ~/.zshrc unless you’re setting up a shared build server or multi-user workstation.

Environment Variables for GUI Apps, Finder, and launchctl

Lx8u2BvWT96aa0E0RjH4KA

When you set an environment variable in Terminal, it lives in that shell session. Apps you launch from Finder (Xcode, VSCode, IntelliJ, whatever) don’t inherit those variables. macOS uses launchd to start GUI applications, and launchd has its own environment separate from your shell.

To make a variable visible to GUI apps, use launchctl setenv VAR value. That command tells launchd to include the variable in the environment it passes to every app it launches. Example:

launchctl setenv JAVA_HOME "/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home"

Once you run that, any app you open from Finder (or Spotlight, or the Dock) will see JAVA_HOME. To check it worked, run launchctl getenv JAVA_HOME. You should see the path printed.

There’s a catch: launchctl setenv doesn’t persist across reboots. To make it stick, you create a LaunchAgent plist in ~/Library/LaunchAgents/ with an EnvironmentVariables dictionary. Here’s the flow:

  1. Create a file like ~/Library/LaunchAgents/environment.plist.
  2. Add a plist structure with a ProgramArguments array that calls launchctl setenv for each variable.
  3. Load the agent with launchctl load ~/Library/LaunchAgents/environment.plist.
  4. Log out and back in (or reboot) to apply it system-wide for GUI apps.
  5. Verify with launchctl getenv VAR.

Older macOS versions used ~/.MacOSX/environment.plist, but Apple deprecated that years ago. Don’t bother with it on Catalina or later. It won’t do anything.

If you only need Terminal apps to see the variable, skip launchctl entirely and just use your shell config file. If you need both Terminal and GUI apps, set the variable in ~/.zshrc and also run launchctl setenv. That covers both contexts.

Verifying macOS Environment Variables and Troubleshooting Issues

3vV-4AcxTdOVB7FTotlz7Q

To see all environment variables in the current shell, run printenv. To check a specific variable, use echo $VAR or printenv VAR. To search for a partial match, pipe to grep: env | grep JAVA.

When a variable doesn’t show up or doesn’t work, here are the usual suspects:

Spaces around the equals sign. export VAR = "value" breaks. Use export VAR="value".

Edited the wrong file. If you’re in zsh but you edited ~/.bash_profile, nothing happens. Check echo $SHELL and match the file.

Forgot to restart Terminal or source the file. Changes to startup files don’t apply to the current session unless you run source ~/.zshrc.

Overwrote PATH instead of appending. Used export PATH="/new/dir" instead of export PATH="/new/dir:$PATH". Result: most commands stop working.

GUI app launched from Finder doesn’t see Terminal variables. Use launchctl setenv or a LaunchAgent plist.

Duplicate or conflicting entries in PATH. Run echo $PATH and look for the same directory repeated multiple times. Clean up your shell config file.

If echo $VAR shows nothing, the variable isn’t set in that session. If printenv VAR returns nothing but echo $VAR works, the variable might be a shell variable (set without export). Only exported variables appear in printenv and get passed to child processes.

For PATH issues, try which commandname to see which binary the shell is finding. If it’s the wrong one, adjust the order in your PATH export. If which returns nothing, the directory isn’t in PATH at all. Add it and reload.

Final Words

You set a temporary variable with export VAR=”value” and checked it with echo $VAR, then learned how to persist it in ~/.zshrc or ~/.bash_profile.

We covered updating PATH, shell differences (zsh, bash, fish), system-wide files, and GUI apps using launchctl, plus quick troubleshooting steps like printenv and restarting Terminal.

Keep the short workflow in mind: export, verify, add to your shell file, source or reopen Terminal, and that’s how you set environment variable mac and keep tools running smoothly. You’ve got this.

FAQ

Q: How do I set a temporary environment variable in macOS?

A: Setting a temporary environment variable on macOS uses the correct syntax export VAR=”value” (no spaces). It lasts only for the current Terminal session; verify with echo $VAR.

Q: What is the correct export syntax and common syntax errors?

A: The correct export syntax is export VAR=”value” with no spaces around =. Incorrect forms like export VAR = value or setenv VAR = value cause zsh syntax errors.

Q: How do I make an environment variable permanent on macOS?

A: Making a variable permanent on macOS means adding an export line to your shell file (e.g., ~/.zshrc or ~/.bash_profile), then run source ~/.zshrc or reopen Terminal to apply it.

Q: Which shell file should I edit: ~/.zshrc, ~/.bash_profile, or ~/.zprofile?

A: Choosing the file depends on your shell: zsh uses ~/.zshrc for interactive shells and ~/.zprofile for login shells; bash uses ~/.bash_profile or ~/.bashrc. Check your shell with echo $SHELL.

Q: How do I update PATH to include new tools without breaking the existing PATH?

A: Update PATH by prepending or appending, for example export PATH=”/new/dir:$PATH” to avoid overwriting. Verify with echo $PATH and fix duplicates in your shell profile.

Q: How do GUI apps get environment variables and how can I set them?

A: GUI apps don’t inherit Terminal variables; use launchctl setenv VAR value for the current GUI session, or create a LaunchAgent plist for persistent GUI environment variables; verify with launchctl getenv VAR.

Q: How can I set system-wide environment variables and when should I use them?

A: Set system-wide vars by editing /etc/profile, /etc/zshrc, /etc/paths, or adding files to /etc/paths.d with sudo. Use for all-user needs and require logout or reboot to take effect.

Q: How do I verify environment variables and troubleshoot common issues?

A: Verify using echo $VAR, printenv VAR, or env | grep VAR. Common failures come from editing the wrong file, adding spaces around =, not restarting Terminal, or GUI apps not inheriting Terminal vars.

Related articles

Recent articles