• Technology
  • February 4, 2026

Set Linux Environment Variables: Permanent & Temporary Methods Guide

So you need to set environment variables in Linux huh? Been there. That moment when you're installing Java or setting up a dev environment and suddenly you're staring at terminal errors because $PATH isn't cooperating. Let's talk real talk about Linux environment variables - no textbook fluff, just what actually works from someone who's messed this up more times than I'd like to admit.

Remember last month? I wasted two hours because my .bashrc edits weren't applying to VSCode. Turns out I forgot that graphical apps don't always see shell variables. We'll cover that landmine later.

What Even Are Linux Environment Variables?

Think of them as sticky notes your system uses to remember important stuff. Like telling apps where to find Java (JAVA_HOME), or where to look for programs (PATH). They're just key-value pairs living in memory:

USER=john
HOME=/home/john
EDITOR=nano

Ever tried running a script and got "command not found"? That's usually PATH acting up. Or seen a Java install fail because it can't find JDK? That's JAVA_HOME missing. These little things cause big headaches.

Why Would You Need to Set Environment Variables in Linux?

A few real scenarios:

  • Your Python script keeps crashing because it can't find the API key (store it in API_KEY)
  • Docker compose won't start because database paths are wrong (use DB_PATH)
  • You're tired of typing /opt/myapp/bin/start.sh every time (add to PATH)

Personally, I set them constantly - for development configs, server secrets (though be careful!), and custom tool locations. Way cleaner than hardcoding paths everywhere.

Setting Environment Variables in Linux: Temporary vs Permanent

Here's where newcomers get tripped up. That variable you set? It might disappear faster than donuts in the break room.

The Quick and Dirty Way (Temporary)

Need something just for this terminal session? Easy:

export TEMP_VAR="This vanishes when I close terminal"

Try it now: Run export TEST=hello then echo $TEST. See? Works. Now close terminal and poof - gone. Good for testing, terrible for anything persistent.

Watch out: Variables set this way don't affect child processes if you use the syntax MY_VAR=value ./script.sh. That variable only exists for that single command!

Making Environment Variables Stick (Permanent)

Ah, the real magic. Where you set them changes who sees them:

File Scope When It Loads My Preference?
~/.bashrc Just you Every new terminal ? Best for dev tools
~/.profile Just you Login shells only When I care about login vs non-login
/etc/environment All users System-wide at login ? For server-wide paths
/etc/profile.d/*.sh All users Every interactive shell Cleanest for system-wide

Here's how I set my PATH in ~/.bashrc:

# Add custom scripts folder to PATH
export PATH="$PATH:/home/john/bin"

After editing? Always run source ~/.bashrc or just reopen your terminal.

Confession time: I dislike /etc/environment because it doesn't support export commands - just raw VAR=VAL pairs. Annoying when you need dynamic values.

Step-by-Step: How to Set Environment Variables in Linux Correctly

Let's walk through a real example - say we're adding a Python virtualenv path:

Edit your .bashrc
nano ~/.bashrc (or use vim if you're fancy)
Add at the bottom:
export MY_PYTHON_ENV="/home/john/.virtualenvs/myproject"
Save and apply:
source ~/.bashrc
Verify:
echo $MY_PYTHON_ENV → Should show your path

But what if it doesn't show?

Last Tuesday I set a variable that wouldn't appear. Turns out I had a typo: exprot instead of export. Bash just ignored it silently. Always double-check!

Setting Environment Variables for All Users

Say you're configuring a server and need JAVA_HOME for everyone:

Create a new file in /etc/profile.d/ (I prefer this over messing with /etc/profile):

sudo nano /etc/profile.d/java.sh

Add:

export JAVA_HOME="/usr/lib/jvm/java-11-openjdk"
export PATH="$PATH:$JAVA_HOME/bin"

Save. Now every new login sees Java. Test with a new user account.

Pro Tip: Filenames in /etc/profile.d/ matter! They're loaded alphabetically. I prefix with numbers like 10-java.sh to control order.

Critical Environment Variables You Absolutely Need to Know

Some variables do heavy lifting:

Variable What It Does Typical Value Why Care?
PATH Where to find executables /usr/bin:/bin Most common troubleshooting headache
HOME Your home directory /home/username Essential for scripts locating user files
USER Current username john Scripts that need to know who's running them
EDITOR Default text editor nano or vim When git asks you to edit commit messages
JAVA_HOME Java installation path /usr/lib/jvm/java-11 Required by almost all Java tools
LD_LIBRARY_PATH Where to find libraries /usr/local/lib Fix "shared library not found" errors

Fun story: Last year I spent 3 hours debugging why a Python lib wouldn't load. Turns out I'd set LD_LIBRARY_PATH in .bashrc but forgot Ubuntu's GUI launchers ignore it. Had to add it to ~/.profile instead.

Troubleshooting: When Setting Environment Variables in Linux Goes Wrong

Let's diagnose common issues:

"I set it but it's not working!"
• Did you source the file after editing?
• Check for typos with printenv | grep VAR
• Trying to access from GUI? Most desktop environments don't load .bashrc

"Changes break my terminal!"
• Accidentally deleted PATH? Boot into recovery mode and fix the file
• Added broken syntax? Check with bash -x ~/.bashrc for errors

"Variable shows in terminal but not in my app!"
• Apps launched from GUI often use different configs
• Try setting in ~/.profile instead of .bashrc
• For systemd services, set in service files instead

Diagnostic Toolkit:
printenv - Show all environment variables
echo $MY_VAR - Check specific variable
env - Similar to printenv
set - Shows shell variables too

Advanced Stuff: What Most Guides Don't Tell You

After a decade of sysadmin work, here's my hard-earned knowledge:

Security Considerations

Never do export DB_PASSWORD="secret" in plain text files! Use:

  • Encrypted config managers like Hashicorp Vault
  • Per-application secret files (with proper permissions!)
  • ~/.bashrc is world-readable? Run chmod 600 ~/.bashrc

GUI Applications & Desktop Launchers

Biggest headache in Linux! Your beautiful .bashrc variables mean nothing to:
• Apps launched from desktop icons
• Scheduled cron jobs
• Systemd services

Solutions:
• For GUI apps: Set variables in ~/.profile or ~/.pam_environment
• For cron: Set vars directly in crontab
• For systemd: Use Environment= in service files

Dynamic Variables

Need today's date in a variable? Possible!

export LOG_FILE="/var/log/myapp-$(date +%Y%m%d).log"

Works in .bashrc but not in /etc/environment. Tradeoffs.

Frankly I wish Linux had a unified way to set environment variables instead of this file soup. But hey, it works.

Environment Variables vs Shell Variables - What's the Diff?

Quick distinction:

LOCAL_VAR="I'm only visible in this shell script"
export GLOBAL_VAR="I'm visible to child processes too"

That export command is what makes it an environment variable. Without it, subcommands won't see it.

The FAQ Section: Actual Questions People Ask

Q: How do I permanently set environment variables in Linux for a single user?
A: Edit ~/.bashrc for terminal sessions or ~/.profile for GUI apps. Use the export command. Q: Where to set environment variables in Linux that affect all users?
A: /etc/environment for simple variables or create .sh files in /etc/profile.d/ for complex ones. Q: Why can't my Ubuntu GUI programs see my environment variables?
A: Desktop environments don't load .bashrc. Use ~/.profile instead, or configure via ~/.config/environment.d/ on systemd systems. Q: How to see all currently set environment variables?
A: Run printenv or just env in terminal. Q: Can I set environment variables for Docker containers?
A: Absolutely! Use -e MY_VAR=value in docker run, or the environment: section in docker-compose.yml. Q: What's the difference between .bashrc and .profile?
A: .bashrc loads for every new bash terminal, .profile loads only when you log into the system. Use .profile for GUI-related variables. Q: How do I remove an environment variable?
A: unset MY_VAR for current session, or remove from config files and source again.

My Dirty Little Environment Variable Secrets

After years of trial and error:

  • I create ~/.env for project-specific vars and source it manually - keeps things isolated
  • Prefix all custom variables with MY_ (like MY_PROJECT_PATH) to avoid collisions
  • For servers, I store environment variables in /etc/opt/myapp/config instead of profile.d - safer for updates
  • Always back up config files before editing! I once corrupted .bashrc and couldn't even open terminal

And my biggest pet peeve? When guides tell you to set environment variables in Linux using /etc/profile - that file gets overwritten on upgrades! Use /etc/profile.d/ instead.

Beyond Basics: Cool Environment Variable Tricks

Level up with these:

Conditional Variables
Only set if directory exists in .bashrc:

if [ -d "/opt/special_tools" ]; then
  export PATH="$PATH:/opt/special_tools"
fi

Alias Shortcuts
Combine with aliases for power moves:

export PROJECTS="$HOME/code"
alias pj="cd $PROJECTS"

Version Switching
Quickly change between tool versions:

# In .bashrc
use_java11() {
  export JAVA_HOME="/usr/lib/jvm/java-11"
}

use_java17() {
  export JAVA_HOME="/usr/lib/jvm/java-17"
}

Call it: use_java17 and boom - switches versions.

Final Reality Check

Look, setting environment variables in Linux feels messy because it is messy. There's no one right way - it depends on your distro, whether you're using GUI, and what needs the variable.

My practical advice?

  • For personal dev work: ~/.bashrc is your friend
  • For system services: Use service-specific configs
  • For GUI apps: ~/.profile or distro-specific locations
  • When in doubt: printenv is the truth-teller

Don't stress about perfection. I've set environment variables incorrectly more times than I've cooked edible rice. The key is understanding why it failed when it does. Now go make that JAVA_HOME behave!

Comment

Recommended Article